diff options
80 files changed, 5766 insertions, 1354 deletions
diff --git a/.travis.yml b/.travis.yml index cf57dc38..b9add8c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,10 +19,11 @@ matrix: DEMO_ARGS: -DABC_NAMESPACE=xxx - os: osx - osx_image: xcode8 - before_install: - - brew update - - brew install readline + osx_image: xcode10 + addons: + homebrew: + packages: + - readline script: @@ -18,7 +18,7 @@ APIs of ABC compiled as a static library. To build the demo program - * Copy demo.cc and libabc.a to the working directory + * Copy demo.c and libabc.a to the working directory * Run `gcc -Wall -g -c demo.c -o demo.o` * Run `g++ -g -o demo demo.o libabc.a -lm -ldl -lreadline -lpthread` @@ -1107,6 +1107,10 @@ SOURCE=.\src\base\acb\acbSets.h # End Source File # Begin Source File +SOURCE=.\src\base\acb\acbTest.c +# End Source File +# Begin Source File + SOURCE=.\src\base\acb\acbUtil.c # End Source File # End Group @@ -4863,6 +4867,10 @@ SOURCE=.\src\aig\gia\giaFx.c # End Source File # Begin Source File +SOURCE=.\src\aig\gia\giaGen.c +# End Source File +# Begin Source File + SOURCE=.\src\aig\gia\giaGig.c # End Source File # Begin Source File @@ -5035,6 +5043,14 @@ SOURCE=.\src\aig\gia\giaSim4.c # End Source File # Begin Source File +SOURCE=.\src\aig\gia\giaSim5.c +# End Source File +# Begin Source File + +SOURCE=.\src\aig\gia\giaSimBase.c +# End Source File +# Begin Source File + SOURCE=.\src\aig\gia\giaSort.c # End Source File # Begin Source File @@ -5211,10 +5227,6 @@ SOURCE=.\src\bool\kit\kit.h # End Source File # Begin Source File -SOURCE=.\src\bool\kit\kit_.c -# End Source File -# Begin Source File - SOURCE=.\src\bool\kit\kitAig.c # End Source File # Begin Source File diff --git a/src/aig/gia/gia.c b/src/aig/gia/gia.c index 8f18f69c..7947a60e 100644 --- a/src/aig/gia/gia.c +++ b/src/aig/gia/gia.c @@ -202,6 +202,101 @@ Gia_Man_t * Slv_ManToAig( Gia_Man_t * pGia ) return pNew; } + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Gia_ManCofPisVars( Gia_Man_t * p, int nVars ) +{ + Gia_Man_t * pNew, * pTemp; + Gia_Obj_t * pObj; int i, m; + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManForEachPi( p, pObj, i ) + Gia_ManAppendCi( pNew ); + Gia_ManHashStart( pNew ); + for ( m = 0; m < (1 << nVars); m++ ) + { + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachPi( p, pObj, i ) + { + if ( i < nVars ) + pObj->Value = (m >> i) & 1; + else + pObj->Value = Gia_ObjToLit(pNew, Gia_ManCi(pNew, i)); + } + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachPo( p, pObj, i ) + Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + } + Gia_ManHashStop( pNew ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManStructExperiment( Gia_Man_t * p ) +{ + extern int Cec_ManVerifyTwo( Gia_Man_t * p0, Gia_Man_t * p1, int fVerbose ); + Gia_Man_t * pTemp, * pUsed; + Vec_Ptr_t * vGias = Vec_PtrAlloc( 100 ); + Gia_Obj_t * pObj; int i, k; + Gia_ManForEachCo( p, pObj, i ) + { + int iFan0 = Gia_ObjFaninId0p(p, pObj); + pTemp = Gia_ManDupAndCones( p, &iFan0, 1, 1 ); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pUsed, k ) + if ( Gia_ManCiNum(pTemp) == Gia_ManCiNum(pUsed) && Cec_ManVerifyTwo(pTemp, pUsed, 0) == 1 ) + { + ABC_SWAP( void *, Vec_PtrArray(vGias)[0], Vec_PtrArray(vGias)[k] ); + break; + } + else + ABC_FREE( pTemp->pCexComb ); + + printf( "\nOut %6d : ", i ); + if ( k == Vec_PtrSize(vGias) ) + printf( "Equiv to none " ); + else + printf( "Equiv to %6d ", k ); + Gia_ManPrintStats( pTemp, NULL ); + + if ( k == Vec_PtrSize(vGias) ) + Vec_PtrPush( vGias, pTemp ); + else + Gia_ManStop( pTemp ); + } + printf( "\nComputed %d classes.\n\n", Vec_PtrSize(vGias) ); + Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i ) + Gia_ManStop( pTemp ); + Vec_PtrFree( vGias ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index 0efc263b..ae9835ee 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -52,6 +52,7 @@ ABC_NAMESPACE_HEADER_START typedef struct Gia_MmFixed_t_ Gia_MmFixed_t; typedef struct Gia_MmFlex_t_ Gia_MmFlex_t; typedef struct Gia_MmStep_t_ Gia_MmStep_t; +typedef struct Gia_Dat_t_ Gia_Dat_t; typedef struct Gia_Rpr_t_ Gia_Rpr_t; struct Gia_Rpr_t_ @@ -204,10 +205,13 @@ struct Gia_Man_t_ int fBuiltInSim; int iPatsPi; int nSimWords; + int nSimWordsT; int iPastPiMax; int nSimWordsMax; Vec_Wrd_t * vSims; + Vec_Wrd_t * vSimsT; Vec_Wrd_t * vSimsPi; + Vec_Wrd_t * vSimsPo; Vec_Int_t * vClassOld; Vec_Int_t * vClassNew; // incremental simulation @@ -231,6 +235,7 @@ struct Gia_Man_t_ Vec_Wrd_t * vSuppWords; // support information Vec_Int_t vCopiesTwo; // intermediate copies Vec_Int_t vSuppVars; // used variables + Gia_Dat_t * pUData; }; @@ -606,6 +611,7 @@ static inline void Gia_ObjSetTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * static inline int Gia_ObjIsTravIdCurrent( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds); } static inline int Gia_ObjIsTravIdPrevious( Gia_Man_t * p, Gia_Obj_t * pObj ) { assert( Gia_ObjId(p, pObj) < p->nTravIdsAlloc ); return (p->pTravIds[Gia_ObjId(p, pObj)] == p->nTravIds - 1); } static inline void Gia_ObjSetTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds; } +static inline void Gia_ObjSetTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); p->pTravIds[Id] = p->nTravIds - 1; } static inline int Gia_ObjIsTravIdCurrentId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds); } static inline int Gia_ObjIsTravIdPreviousId( Gia_Man_t * p, int Id ) { assert( Id < p->nTravIdsAlloc ); return (p->pTravIds[Id] == p->nTravIds - 1); } @@ -718,8 +724,8 @@ static inline int Gia_ManAppendXorReal( Gia_Man_t * p, int iLit0, int iLit1 ) assert( iLit0 >= 0 && Abc_Lit2Var(iLit0) < Gia_ManObjNum(p) ); assert( iLit1 >= 0 && Abc_Lit2Var(iLit1) < Gia_ManObjNum(p) ); assert( Abc_Lit2Var(iLit0) != Abc_Lit2Var(iLit1) ); - assert( !Abc_LitIsCompl(iLit0) ); - assert( !Abc_LitIsCompl(iLit1) ); + //assert( !Abc_LitIsCompl(iLit0) ); + //assert( !Abc_LitIsCompl(iLit1) ); if ( Abc_Lit2Var(iLit0) > Abc_Lit2Var(iLit1) ) { pObj->iDiff0 = (unsigned)(Gia_ObjId(p, pObj) - Abc_Lit2Var(iLit0)); @@ -852,7 +858,6 @@ static inline int Gia_ManAppendXor2( Gia_Man_t * p, int iLit0, int iLit1 ) static inline int Gia_ManAppendXorReal2( Gia_Man_t * p, int iLit0, int iLit1 ) { - int fCompl; if ( !p->fGiaSimple ) { if ( iLit0 < 2 ) @@ -864,8 +869,7 @@ static inline int Gia_ManAppendXorReal2( Gia_Man_t * p, int iLit0, int iLit1 ) if ( iLit0 == Abc_LitNot(iLit1) ) return 1; } - fCompl = Abc_LitIsCompl(iLit0) ^ Abc_LitIsCompl(iLit1); - return Abc_LitNotCond( Gia_ManAppendXorReal( p, Abc_LitRegular(iLit0), Abc_LitRegular(iLit1) ), fCompl ); + return Gia_ManAppendXorReal( p, iLit0, iLit1 ); } static inline void Gia_ManPatchCoDriver( Gia_Man_t * p, int iCoIndex, int iLit0 ) @@ -1508,7 +1512,7 @@ extern void Gia_ManWriteMiniLut( Gia_Man_t * pGia, char * pFileNa extern void Gia_ManCountMuxXor( Gia_Man_t * p, int * pnMuxes, int * pnXors ); extern void Gia_ManPrintMuxStats( Gia_Man_t * p ); extern Gia_Man_t * Gia_ManDupMuxes( Gia_Man_t * p, int Limit ); -extern Gia_Man_t * Gia_ManDupNoMuxes( Gia_Man_t * p ); +extern Gia_Man_t * Gia_ManDupNoMuxes( Gia_Man_t * p, int fSkipBufs ); /*=== giaPat.c ===========================================================*/ extern void Gia_SatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vCex, Vec_Int_t * vVisit ); /*=== giaRetime.c ===========================================================*/ diff --git a/src/aig/gia/giaBalAig.c b/src/aig/gia/giaBalAig.c index a3a0719e..5603b410 100644 --- a/src/aig/gia/giaBalAig.c +++ b/src/aig/gia/giaBalAig.c @@ -449,7 +449,7 @@ Gia_Man_t * Gia_ManBalance( Gia_Man_t * p, int fSimpleAnd, int fStrict, int fVer Gia_ManTransferTiming( pNew1, pNew ); if ( fVerbose ) Gia_ManPrintStats( pNew1, NULL ); Gia_ManStop( pNew ); - pNew2 = Gia_ManDupNoMuxes( pNew1 ); + pNew2 = Gia_ManDupNoMuxes( pNew1, 0 ); Gia_ManTransferTiming( pNew2, pNew1 ); if ( fVerbose ) Gia_ManPrintStats( pNew2, NULL ); Gia_ManStop( pNew1 ); @@ -1083,7 +1083,7 @@ Gia_Man_t * Gia_ManAreaBalance( Gia_Man_t * p, int fSimpleAnd, int nNewNodesMax, Gia_ManStop( pNew ); Vec_IntFreeP( &vCiLevels ); // derive the final result - pNew2 = Gia_ManDupNoMuxes( pNew1 ); + pNew2 = Gia_ManDupNoMuxes( pNew1, 0 ); Gia_ManTransferTiming( pNew2, pNew1 ); if ( fVerbose ) Gia_ManPrintStats( pNew2, NULL ); Gia_ManStop( pNew1 ); diff --git a/src/aig/gia/giaBalLut.c b/src/aig/gia/giaBalLut.c index 4402e36f..c90910c9 100644 --- a/src/aig/gia/giaBalLut.c +++ b/src/aig/gia/giaBalLut.c @@ -965,7 +965,7 @@ Gia_Man_t * Gia_ManBalanceLut( Gia_Man_t * p, int nLutSize, int nCutNum, int fVe pNew1 = Gia_ManBalanceInt( pNew, nLutSize, nCutNum, fVerbose ); if ( fVerbose ) Gia_ManPrintStats( pNew1, NULL ); Gia_ManStop( pNew ); - pNew2 = Gia_ManDupNoMuxes( pNew1 ); + pNew2 = Gia_ManDupNoMuxes( pNew1, 0 ); if ( fVerbose ) Gia_ManPrintStats( pNew2, NULL ); Gia_ManStop( pNew1 ); return pNew2; diff --git a/src/aig/gia/giaCSat2.c b/src/aig/gia/giaCSat2.c index ee0ce311..a9739e02 100644 --- a/src/aig/gia/giaCSat2.c +++ b/src/aig/gia/giaCSat2.c @@ -1653,9 +1653,12 @@ Vec_Int_t * Cbs2_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvS p->timeTotal = Abc_Clock() - clkTotal; if ( fVerbose ) Cbs2_ManSatPrintStats( p ); + if ( fVerbose ) + { // printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro ); printf( "Prop1 = %d. Prop2 = %d. Prop3 = %d. ClaConf = %d. FailJ = %d. FailC = %d. ", p->nPropCalls[0], p->nPropCalls[1], p->nPropCalls[2], p->nClauseConf, p->nFails[0], p->nFails[1] ); Abc_PrintTime( 1, "JFront", p->timeJFront ); + } Cbs2_ManStop( p ); *pvStatus = vStatus; diff --git a/src/aig/gia/giaDup.c b/src/aig/gia/giaDup.c index 21b6f03a..4f448c40 100644 --- a/src/aig/gia/giaDup.c +++ b/src/aig/gia/giaDup.c @@ -3473,7 +3473,10 @@ Gia_Man_t * Gia_ManDupCones( Gia_Man_t * p, int * pPos, int nPos, int fTrimPis ) Gia_ObjRiToRo(p, pObj)->Value = Gia_ManAppendCi( pNew ); // create internal nodes Vec_PtrForEachEntry( Gia_Obj_t *, vNodes, pObj, i ) - pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + if ( Gia_ObjIsXor(pObj) ) + pObj->Value = Gia_ManAppendXor( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + else + pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); // create COs Vec_PtrForEachEntry( Gia_Obj_t *, vRoots, pObj, i ) Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); diff --git a/src/aig/gia/giaEquiv.c b/src/aig/gia/giaEquiv.c index db1563fc..03b9b819 100644 --- a/src/aig/gia/giaEquiv.c +++ b/src/aig/gia/giaEquiv.c @@ -185,6 +185,7 @@ Gia_Man_t * Gia_ManComputeGiaEquivs( Gia_Man_t * pGia, int nConfs, int fVerbose Gia_Man_t * pTemp; Cec_ParFra_t ParsFra, * pPars = &ParsFra; Cec_ManFraSetDefaultParams( pPars ); + pPars->nItersMax = 100; pPars->fUseOrigIds = 1; pPars->fSatSweeping = 1; pPars->nBTLimit = nConfs; @@ -508,6 +509,67 @@ void Gia_ManEquivPrintClasses( Gia_Man_t * p, int fVerbose, float Mem ) } } + +/**Function************************************************************* + + Synopsis [Map representatives into class members with minimum level.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManChoiceMinLevel_rec( Gia_Man_t * p, int iPivot, int fDiveIn, Vec_Int_t * vMap ) +{ + int Level0, Level1, LevelMax; + Gia_Obj_t * pPivot = Gia_ManObj( p, iPivot ); + if ( Gia_ObjIsCi(pPivot) ) + return 0; + if ( Gia_ObjLevel(p, pPivot) ) + return Gia_ObjLevel(p, pPivot); + if ( fDiveIn && Gia_ObjIsClass(p, iPivot) ) + { + int iObj, ObjMin = -1, iRepr = Gia_ObjRepr(p, iPivot), LevMin = ABC_INFINITY; + Gia_ClassForEachObj( p, iRepr, iObj ) + { + int LevCur = Gia_ManChoiceMinLevel_rec( p, iObj, 0, vMap ); + if ( LevMin > LevCur ) + { + LevMin = LevCur; + ObjMin = iObj; + } + } + assert( LevMin > 0 ); + Vec_IntWriteEntry( vMap, iRepr, ObjMin ); + Gia_ClassForEachObj( p, iRepr, iObj ) + Gia_ObjSetLevelId( p, iObj, LevMin ); + return LevMin; + } + assert( Gia_ObjIsAnd(pPivot) ); + Level0 = Gia_ManChoiceMinLevel_rec( p, Gia_ObjFaninId0(pPivot, iPivot), 1, vMap ); + Level1 = Gia_ManChoiceMinLevel_rec( p, Gia_ObjFaninId1(pPivot, iPivot), 1, vMap ); + LevelMax = 1 + Abc_MaxInt(Level0, Level1); + Gia_ObjSetLevel( p, pPivot, LevelMax ); + return LevelMax; +} +Vec_Int_t * Gia_ManChoiceMinLevel( Gia_Man_t * p ) +{ + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Gia_Obj_t * pObj; + int i, LevelCur, LevelMax = 0; +// assert( Gia_ManRegNum(p) == 0 ); + Gia_ManCleanLevels( p, Gia_ManObjNum(p) ); + Gia_ManForEachCo( p, pObj, i ) + { + LevelCur = Gia_ManChoiceMinLevel_rec( p, Gia_ObjFaninId0p(p, pObj), 1, vMap ); + LevelMax = Abc_MaxInt(LevelMax, LevelCur); + } + //printf( "Max level %d\n", LevelMax ); + return vMap; +} + /**Function************************************************************* Synopsis [Returns representative node.] @@ -583,15 +645,24 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fS int i; if ( !p->pReprs && p->pSibls ) { + int * pMap = ABC_FALLOC( int, Gia_ManObjNum(p) ); p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); for ( i = 0; i < Gia_ManObjNum(p); i++ ) Gia_ObjSetRepr( p, i, GIA_VOID ); for ( i = 0; i < Gia_ManObjNum(p); i++ ) if ( p->pSibls[i] > 0 ) - Gia_ObjSetRepr( p, i, p->pSibls[i] ); - printf( "Created equivalence classes.\n" ); + { + if ( pMap[p->pSibls[i]] == -1 ) + pMap[p->pSibls[i]] = p->pSibls[i]; + pMap[i] = pMap[p->pSibls[i]]; + } + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + if ( p->pSibls[i] > 0 ) + Gia_ObjSetRepr( p, i, pMap[i] ); + //printf( "Created equivalence classes.\n" ); ABC_FREE( p->pNexts ); p->pNexts = Gia_ManDeriveNexts( p ); + ABC_FREE( pMap ); } if ( !p->pReprs ) { @@ -643,6 +714,101 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fS /**Function************************************************************* + Synopsis [Duplicates the AIG in the DFS order.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManEquivReduce2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vMap, int fDiveIn ) +{ + Gia_Obj_t * pRepr; + if ( ~pObj->Value ) + return; + assert( Gia_ObjIsAnd(pObj) ); + if ( fDiveIn && (pRepr = Gia_ManEquivRepr(p, pObj, 1, 0)) ) + { + int iTemp, iRepr = Gia_ObjId(p, pRepr); + Gia_Obj_t * pRepr2 = Gia_ManObj( p, Vec_IntEntry(vMap, iRepr) ); + Gia_ManEquivReduce2_rec( pNew, p, pRepr2, vMap, 0 ); + Gia_ClassForEachObj( p, iRepr, iTemp ) + { + Gia_Obj_t * pTemp = Gia_ManObj(p, iTemp); + pTemp->Value = Abc_LitNotCond( pRepr2->Value, Gia_ObjPhaseReal(pRepr2) ^ Gia_ObjPhaseReal(pTemp) ); + } + assert( ~pObj->Value ); + assert( ~pRepr->Value ); + assert( ~pRepr2->Value ); + return; + } + Gia_ManEquivReduce2_rec( pNew, p, Gia_ObjFanin0(pObj), vMap, 1 ); + Gia_ManEquivReduce2_rec( pNew, p, Gia_ObjFanin1(pObj), vMap, 1 ); + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); +} +Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p ) +{ + Vec_Int_t * vMap; + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i; + if ( !p->pReprs && p->pSibls ) + { + int * pMap = ABC_FALLOC( int, Gia_ManObjNum(p) ); + p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + Gia_ObjSetRepr( p, i, GIA_VOID ); + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + if ( p->pSibls[i] > 0 ) + { + if ( pMap[p->pSibls[i]] == -1 ) + pMap[p->pSibls[i]] = p->pSibls[i]; + pMap[i] = pMap[p->pSibls[i]]; + } + for ( i = 0; i < Gia_ManObjNum(p); i++ ) + if ( p->pSibls[i] > 0 ) + Gia_ObjSetRepr( p, i, pMap[i] ); + //printf( "Created equivalence classes.\n" ); + ABC_FREE( p->pNexts ); + p->pNexts = Gia_ManDeriveNexts( p ); + ABC_FREE( pMap ); + } + if ( !p->pReprs ) + { + Abc_Print( 1, "Gia_ManEquivReduce(): Equivalence classes are not available.\n" ); + return NULL; + } + // check if there are any equivalences defined + Gia_ManForEachObj( p, pObj, i ) + if ( Gia_ObjReprObj(p, i) != NULL ) + break; + if ( i == Gia_ManObjNum(p) ) + return Gia_ManDup( p ); + vMap = Gia_ManChoiceMinLevel( p ); + Gia_ManSetPhase( p ); + 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_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + Gia_ManHashAlloc( pNew ); + Gia_ManForEachCo( p, pObj, i ) + Gia_ManEquivReduce2_rec( pNew, p, Gia_ObjFanin0(pObj), vMap, 1 ); + Gia_ManForEachCo( p, pObj, i ) + pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); + Gia_ManHashStop( pNew ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Vec_IntFree( vMap ); + return pNew; +} + + +/**Function************************************************************* + Synopsis [Reduces AIG using equivalence classes.] Description [] diff --git a/src/aig/gia/giaFanout.c b/src/aig/gia/giaFanout.c index 6a940354..44e79ba2 100644 --- a/src/aig/gia/giaFanout.c +++ b/src/aig/gia/giaFanout.c @@ -214,7 +214,7 @@ Vec_Int_t * Gia_ManStartFanoutMap( Gia_Man_t * p, Vec_Int_t * vFanoutNums ) Gia_Obj_t * pObj; int i, iOffset; iOffset = Gia_ManObjNum(p); - vEdgeMap = Vec_IntStart( iOffset + Gia_ManMuxNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManCoNum(p) ); + vEdgeMap = Vec_IntStart( iOffset + Gia_ManMuxNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManCoNum(p) - Gia_ManBufNum(p) ); Gia_ManForEachObj( p, pObj, i ) { Vec_IntWriteEntry( vEdgeMap, i, iOffset ); @@ -261,9 +261,8 @@ void Gia_ManStaticFanoutStart( Gia_Man_t * p ) Gia_ObjSetFanout( p, pFanin, iFanout, pObj ); Vec_IntAddToEntry( vCounts, Gia_ObjId(p, pFanin), 1 ); } - if ( Gia_ObjIsAnd(pObj) ) + if ( Gia_ObjIsAnd(pObj) && !Gia_ObjIsBuf(pObj) ) { - pFanin = Gia_ObjFanin1(pObj); iFanout = Vec_IntEntry( vCounts, Gia_ObjId(p, pFanin) ); Gia_ObjSetFanout( p, pFanin, iFanout, pObj ); diff --git a/src/aig/gia/giaGen.c b/src/aig/gia/giaGen.c new file mode 100644 index 00000000..94d561cc --- /dev/null +++ b/src/aig/gia/giaGen.c @@ -0,0 +1,472 @@ +/**CFile**************************************************************** + + FileName [giaGen.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaGen.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "misc/util/utilTruth.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Populate internal simulation info.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline word * Gia_ManObjSim( Gia_Man_t * p, int iObj ) +{ + return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); +} +static inline void Gia_ManObjSimPi( Gia_Man_t * p, int iObj ) +{ + int w; + word * pSim = Gia_ManObjSim( p, iObj ); + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = Gia_ManRandomW( 0 ); +// pSim[0] <<= 1; +} +static inline void Gia_ManObjSimPo( Gia_Man_t * p, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSimCo = Gia_ManObjSim( p, iObj ); + word * pSimDri = Gia_ManObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSimCo[w] = ~pSimDri[w]; + else + for ( w = 0; w < p->nSimWords; w++ ) + pSimCo[w] = pSimDri[w]; +} +static inline void Gia_ManObjSimAnd( Gia_Man_t * p, int iObj ) +{ + int w; + Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); + word * pSim = Gia_ManObjSim( p, iObj ); + word * pSim0 = Gia_ManObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); + word * pSim1 = Gia_ManObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); + if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = ~pSim0[w] & ~pSim1[w]; + else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = ~pSim0[w] & pSim1[w]; + else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = pSim0[w] & ~pSim1[w]; + else + for ( w = 0; w < p->nSimWords; w++ ) + pSim[w] = pSim0[w] & pSim1[w]; +} +int Gia_ManSimulateWords( Gia_Man_t * p, int nWords ) +{ + Gia_Obj_t * pObj; int i; + // allocate simulation info for one timeframe + Vec_WrdFreeP( &p->vSims ); + p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords ); + p->nSimWords = nWords; + // perform simulation + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + Gia_ManObjSimAnd( p, i ); + else if ( Gia_ObjIsCi(pObj) ) + Gia_ManObjSimPi( p, i ); + else if ( Gia_ObjIsCo(pObj) ) + Gia_ManObjSimPo( p, i ); + else assert( 0 ); + } + return 1; +} + +int Gia_ManSimulateWordsInit( Gia_Man_t * p, Vec_Wrd_t * vSimsIn ) +{ + Gia_Obj_t * pObj; int i, Id; + int nWords = Vec_WrdSize(vSimsIn) / Gia_ManCiNum(p); + assert( Vec_WrdSize(vSimsIn) == nWords * Gia_ManCiNum(p) ); + // allocate simulation info for one timeframe + Vec_WrdFreeP( &p->vSims ); + p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords ); + p->nSimWords = nWords; + // set input sim info + Gia_ManForEachCiId( p, Id, i ) + memcpy( Vec_WrdEntryP(p->vSims, Id*nWords), Vec_WrdEntryP(vSimsIn, i*nWords), sizeof(word)*nWords ); + // perform simulation + Gia_ManForEachObj1( p, pObj, i ) + { + if ( Gia_ObjIsAnd(pObj) ) + Gia_ManObjSimAnd( p, i ); + else if ( Gia_ObjIsCi(pObj) ) + continue; + else if ( Gia_ObjIsCo(pObj) ) + Gia_ManObjSimPo( p, i ); + else assert( 0 ); + } + return 1; +} + +/**Function************************************************************* + + Synopsis [Dump data files.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDumpFiles( Gia_Man_t * p, int nCexesT, int nCexesV, int Seed, char * pFileName ) +{ + int n, nSize[2] = {nCexesT*64, nCexesV*64}; + + char pFileNameOutTX[100]; + char pFileNameOutTY[100]; + char pFileNameOutVX[100]; + char pFileNameOutVY[100]; + char pFileNameOut[100]; + + //sprintf( pFileNameOutTX, "train_%s_%d_%d.data", pFileName ? pFileName : Gia_ManName(p), nSize[0], Gia_ManCiNum(p) ); + //sprintf( pFileNameOutTY, "train_%s_%d_%d.data", pFileName ? pFileName : Gia_ManName(p), nSize[0], Gia_ManCoNum(p) ); + //sprintf( pFileNameOutVX, "test_%s_%d_%d.data", pFileName ? pFileName : Gia_ManName(p), nSize[1], Gia_ManCiNum(p) ); + //sprintf( pFileNameOutVY, "test_%s_%d_%d.data", pFileName ? pFileName : Gia_ManName(p), nSize[1], Gia_ManCoNum(p) ); + + sprintf( pFileNameOutTX, "%s_x.train.data", pFileName ? pFileName : Gia_ManName(p) ); + sprintf( pFileNameOutTY, "%s_y.train.data", pFileName ? pFileName : Gia_ManName(p) ); + sprintf( pFileNameOutVX, "%s_x.test.data", pFileName ? pFileName : Gia_ManName(p) ); + sprintf( pFileNameOutVY, "%s_y.test.data", pFileName ? pFileName : Gia_ManName(p) ); + + Gia_ManRandomW( 1 ); + for ( n = 0; n < Seed; n++ ) + Gia_ManRandomW( 0 ); + for ( n = 0; n < 2; n++ ) + { + int Res = Gia_ManSimulateWords( p, nSize[n] ); + + Vec_Bit_t * vBitX = Vec_BitAlloc( nSize[n] * Gia_ManCiNum(p) ); + Vec_Bit_t * vBitY = Vec_BitAlloc( nSize[n] * Gia_ManCoNum(p) ); + + FILE * pFileOutX = fopen( n ? pFileNameOutVX : pFileNameOutTX, "wb" ); + FILE * pFileOutY = fopen( n ? pFileNameOutVY : pFileNameOutTY, "wb" ); + + int i, k, Id, Num, Value, nBytes; + for ( k = 0; k < nSize[n]; k++ ) + { + Gia_ManForEachCiId( p, Id, i ) + { + Vec_BitPush( vBitX, Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); + //printf( "%d", Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); + } + //printf( " " ); + Gia_ManForEachCoId( p, Id, i ) + { + Vec_BitPush( vBitY, Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); + //printf( "%d", Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); + } + //printf( "\n" ); + } + assert( Vec_BitSize(vBitX) <= Vec_BitCap(vBitX) ); + assert( Vec_BitSize(vBitY) <= Vec_BitCap(vBitY) ); + + Num = 2; Value = fwrite( &Num, 1, 4, pFileOutX ); assert( Value == 4 ); + Num = nSize[n]; Value = fwrite( &Num, 1, 4, pFileOutX ); assert( Value == 4 ); + Num = Gia_ManCiNum(p); Value = fwrite( &Num, 1, 4, pFileOutX ); assert( Value == 4 ); + + nBytes = nSize[n] * Gia_ManCiNum(p) / 8; + assert( nSize[n] * Gia_ManCiNum(p) % 8 == 0 ); + Value = fwrite( Vec_BitArray(vBitX), 1, nBytes, pFileOutX ); + assert( Value == nBytes ); + + Num = 2; Value = fwrite( &Num, 1, 4, pFileOutY ); assert( Value == 4 ); + Num = nSize[n]; Value = fwrite( &Num, 1, 4, pFileOutY ); assert( Value == 4 ); + Num = Gia_ManCoNum(p); Value = fwrite( &Num, 1, 4, pFileOutY ); assert( Value == 4 ); + + nBytes = nSize[n] * Gia_ManCoNum(p) / 8; + assert( nSize[n] * Gia_ManCoNum(p) % 8 == 0 ); + Value = fwrite( Vec_BitArray(vBitY), 1, nBytes, pFileOutY ); + assert( Value == nBytes ); + + fclose( pFileOutX ); + fclose( pFileOutY ); + + Vec_BitFree( vBitX ); + Vec_BitFree( vBitY ); + + Res = 0; + } + printf( "Finished dumping files \"%s\" and \"%s\".\n", pFileNameOutTX, pFileNameOutTY ); + printf( "Finished dumping files \"%s\" and \"%s\".\n", pFileNameOutVX, pFileNameOutVY ); + + sprintf( pFileNameOut, "%s.flist", pFileName ? pFileName : Gia_ManName(p) ); + { + FILE * pFile = fopen( pFileNameOut, "wb" ); + fprintf( pFile, "%s\n", pFileNameOutTX ); + fprintf( pFile, "%s\n", pFileNameOutTY ); + fprintf( pFile, "%s\n", pFileNameOutVX ); + fprintf( pFile, "%s\n", pFileNameOutVY ); + fclose( pFile ); + printf( "Finished dumping file list \"%s\".\n", pFileNameOut ); + } +} + +/**Function************************************************************* + + Synopsis [Dump data files.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManDumpPlaFiles( Gia_Man_t * p, int nCexesT, int nCexesV, int Seed, char * pFileName ) +{ + int n, nSize[3] = {nCexesT, nCexesV, nCexesV}; + + char pFileNameOut[3][100]; + + sprintf( pFileNameOut[0], "%s.train.pla", pFileName ? pFileName : Gia_ManName(p) ); + sprintf( pFileNameOut[1], "%s.valid.pla", pFileName ? pFileName : Gia_ManName(p) ); + sprintf( pFileNameOut[2], "%s.test.pla", pFileName ? pFileName : Gia_ManName(p) ); + + Gia_ManRandomW( 1 ); + for ( n = 0; n < Seed; n++ ) + Gia_ManRandomW( 0 ); + for ( n = 0; n < 3; n++ ) + { + int Res = Gia_ManSimulateWords( p, nSize[n] ); + int i, k, Id; + + FILE * pFileOut = fopen( pFileNameOut[n], "wb" ); + + fprintf( pFileOut, ".i %d\n", Gia_ManCiNum(p) ); + fprintf( pFileOut, ".o %d\n", Gia_ManCoNum(p) ); + fprintf( pFileOut, ".p %d\n", nSize[n]*64 ); + fprintf( pFileOut, ".type fr\n" ); + for ( k = 0; k < nSize[n]*64; k++ ) + { + Gia_ManForEachCiId( p, Id, i ) + { + //Vec_BitPush( vBitX, Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); + fprintf( pFileOut, "%d", Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); + } + fprintf( pFileOut, " " ); + Gia_ManForEachCoId( p, Id, i ) + { + //Vec_BitPush( vBitY, Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); + fprintf( pFileOut, "%d", Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); + } + fprintf( pFileOut, "\n" ); + } + fprintf( pFileOut, ".e\n" ); + + fclose( pFileOut ); + + Res = 0; + } + printf( "Finished dumping files: \"%s.{train, valid, test}.pla\".\n", pFileName ? pFileName : Gia_ManName(p) ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimLogStats( Gia_Man_t * p, char * pDumpFile, int Total, int Correct, int Guess ) +{ + FILE * pTable = fopen( pDumpFile, "wb" ); + fprintf( pTable, "{\n" ); + fprintf( pTable, " \"name\" : \"%s\",\n", p->pName ); + fprintf( pTable, " \"input\" : %d,\n", Gia_ManCiNum(p) ); + fprintf( pTable, " \"output\" : %d,\n", Gia_ManCoNum(p) ); + fprintf( pTable, " \"and\" : %d,\n", Gia_ManAndNum(p) ); + fprintf( pTable, " \"level\" : %d,\n", Gia_ManLevelNum(p) ); + fprintf( pTable, " \"total\" : %d,\n", Total ); + fprintf( pTable, " \"correct\" : %d,\n", Correct ); + fprintf( pTable, " \"guess\" : %d\n", Guess ); + fprintf( pTable, "}\n" ); + fclose( pTable ); +} +int Gia_ManSimParamRead( char * pFileName, int * pnIns, int * pnWords ) +{ + int c, nIns = -1, nLines = 0, Count = 0, fReadDot = 0; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return 0; + } + while ( (c = fgetc(pFile)) != EOF ) + { + if ( c == '.' ) + fReadDot = 1; + if ( c == '\n' ) + { + if ( !fReadDot ) + { + if ( nIns == -1 ) + nIns = Count; + else if ( nIns != Count ) + { + printf( "The number of symbols (%d) does not match other lines (%d).\n", Count, nIns ); + fclose( pFile ); + return 0; + } + Count = 0; + nLines++; + } + fReadDot = 0; + } + if ( fReadDot ) + continue; + if ( c != '0' && c != '1' ) + continue; + Count++; + } + if ( nLines % 64 > 0 ) + { + printf( "The number of lines (%d) is not divisible by 64.\n", nLines ); + fclose( pFile ); + return 0; + } + *pnIns = nIns - 1; + *pnWords = nLines / 64; + //printf( "Expecting %d inputs and %d words of simulation data.\n", *pnIns, *pnWords ); + fclose( pFile ); + return 1; +} +void Gia_ManSimFileRead( char * pFileName, int nIns, int nWords, Vec_Wrd_t * vSimsIn, Vec_Int_t * vValues ) +{ + int c, nPats = 0, Count = 0, fReadDot = 0; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return; + } + assert( Vec_WrdSize(vSimsIn) % nWords == 0 ); + while ( (c = fgetc(pFile)) != EOF ) + { + if ( c == '.' ) + fReadDot = 1; + if ( c == '\n' ) + fReadDot = 0; + if ( fReadDot ) + continue; + if ( c != '0' && c != '1' ) + continue; + if ( Count == nIns ) + { + Vec_IntPush( vValues, c - '0' ); + Count = 0; + nPats++; + } + else + { + if ( c == '1' ) + Abc_TtSetBit( Vec_WrdEntryP(vSimsIn, Count * nWords), nPats ); + Count++; + } + } + assert( nPats == 64*nWords ); + fclose( pFile ); + printf( "Finished reading %d simulation patterns for %d inputs. Probability of 1 at the output is %6.2f %%.\n", 64*nWords, nIns, 100.0*Vec_IntSum(vValues)/nPats ); +} +void Gia_ManCompareValues( Gia_Man_t * p, Vec_Wrd_t * vSimsIn, Vec_Int_t * vValues, char * pDumpFile ) +{ + int i, Value, Guess, Count = 0, nWords = Vec_WrdSize(vSimsIn) / Gia_ManCiNum(p); + word * pSims; + assert( Vec_IntSize(vValues) == nWords * 64 ); + Gia_ManSimulateWordsInit( p, vSimsIn ); + assert( p->nSimWords == nWords ); + pSims = Gia_ManObjSim( p, Gia_ObjId(p, Gia_ManCo(p, 0)) ); + Vec_IntForEachEntry( vValues, Value, i ) + if ( Abc_TtGetBit(pSims, i) == Value ) + Count++; + Guess = (Vec_IntSum(vValues) > nWords * 32) ? Vec_IntSum(vValues) : nWords * 64 - Vec_IntSum(vValues); + printf( "Total = %6d. Errors = %6d. Correct = %6d. (%6.2f %%) Naive guess = %6d. (%6.2f %%)\n", + Vec_IntSize(vValues), Vec_IntSize(vValues) - Count, + Count, 100.0*Count/Vec_IntSize(vValues), + Guess, 100.0*Guess/Vec_IntSize(vValues)); + if ( pDumpFile == NULL ) + return; + Gia_ManSimLogStats( p, pDumpFile, Vec_IntSize(vValues), Count, Guess ); + printf( "Finished dumping statistics into file \"%s\".\n", pDumpFile ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManTestOneFile( Gia_Man_t * p, char * pFileName, char * pDumpFile ) +{ + Vec_Wrd_t * vSimsIn; + Vec_Int_t * vValues; + int nIns, nWords; + if ( !Gia_ManSimParamRead( pFileName, &nIns, &nWords ) ) + return; + if ( nIns != Gia_ManCiNum(p) ) + { + printf( "The number of inputs in the file \"%s\" (%d) does not match the AIG (%d).\n", pFileName, nIns, Gia_ManCiNum(p) ); + return; + } + vSimsIn = Vec_WrdStart( nIns * nWords ); + vValues = Vec_IntAlloc( nWords * 64 ); + Gia_ManSimFileRead( pFileName, nIns, nWords, vSimsIn, vValues ); + Gia_ManCompareValues( p, vSimsIn, vValues, pDumpFile ); + Vec_WrdFree( vSimsIn ); + Vec_IntFree( vValues ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaMan.c b/src/aig/gia/giaMan.c index 8df96ee0..4ca9bfa4 100644 --- a/src/aig/gia/giaMan.c +++ b/src/aig/gia/giaMan.c @@ -81,6 +81,8 @@ Gia_Man_t * Gia_ManStart( int nObjsMax ) ***********************************************************************/ void Gia_ManStop( Gia_Man_t * p ) { + extern void Gia_DatFree( Gia_Dat_t * p ); + Gia_DatFree( p->pUData ); if ( p->vSeqModelVec ) Vec_PtrFreeFree( p->vSeqModelVec ); Gia_ManStaticFanoutStop( p ); @@ -94,7 +96,9 @@ void Gia_ManStop( Gia_Man_t * p ) Vec_IntFreeP( &p->vClassNew ); Vec_IntFreeP( &p->vClassOld ); Vec_WrdFreeP( &p->vSims ); + Vec_WrdFreeP( &p->vSimsT ); Vec_WrdFreeP( &p->vSimsPi ); + Vec_WrdFreeP( &p->vSimsPo ); Vec_IntFreeP( &p->vTimeStamps ); Vec_FltFreeP( &p->vTiming ); Vec_VecFreeP( &p->vClockDoms ); @@ -484,6 +488,7 @@ void Gia_ManLogAigStats( Gia_Man_t * p, char * pDumpFile ) void Gia_ManPrintStats( Gia_Man_t * p, Gps_Par_t * pPars ) { extern float Gia_ManLevelAve( Gia_Man_t * p ); + int fHaveLevels = p->vLevels != NULL; if ( pPars && pPars->fMiter ) { Gia_ManPrintStatsMiter( p, 0 ); @@ -539,7 +544,8 @@ void Gia_ManPrintStats( Gia_Man_t * p, Gps_Par_t * pPars ) Abc_Print( 1, " %s(%.2f)%s", "\033[1;35m", Gia_ManLevelAve(p), "\033[0m" ); #endif } - Vec_IntFreeP( &p->vLevels ); + if ( !fHaveLevels ) + Vec_IntFreeP( &p->vLevels ); if ( pPars && pPars->fCut ) Abc_Print( 1, " cut = %d(%d)", Gia_ManCrossCut(p, 0), Gia_ManCrossCut(p, 1) ); Abc_Print( 1, " mem =%5.2f MB", Gia_ManMemory(p)/(1<<20) ); @@ -551,6 +557,8 @@ void Gia_ManPrintStats( Gia_Man_t * p, Gps_Par_t * pPars ) Abc_Print( 1, " bb = %d", Gia_ManBlackBoxNum(p) ); if ( Gia_ManBufNum(p) ) Abc_Print( 1, " buf = %d", Gia_ManBufNum(p) ); + if ( Gia_ManXorNum(p) && p->pMuxes == NULL ) + Abc_Print( 1, " xor = %d", Gia_ManXorNum(p) ); if ( pPars && pPars->fMuxXor ) printf( "\nXOR/MUX " ), Gia_ManPrintMuxStats( p ); if ( pPars && pPars->fSwitch ) diff --git a/src/aig/gia/giaMfs.c b/src/aig/gia/giaMfs.c index 5890f84c..d443ddde 100644 --- a/src/aig/gia/giaMfs.c +++ b/src/aig/gia/giaMfs.c @@ -470,6 +470,7 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes ) // duplicated initial state if ( p->vRegInits ) pNew->vRegInits = Vec_IntDup( p->vRegInits ); + pNew->nAnd2Delay = p->nAnd2Delay; // cleanup Vec_WecFree( vGroups ); diff --git a/src/aig/gia/giaMini.c b/src/aig/gia/giaMini.c index 78d99ca8..ce42f73c 100644 --- a/src/aig/gia/giaMini.c +++ b/src/aig/gia/giaMini.c @@ -317,6 +317,7 @@ Mini_Lut_t * Gia_ManToMiniLut( Gia_Man_t * pGia ) p = Mini_LutStart( LutSize ); // create primary inputs Gia_ManFillValue( pGia ); + Gia_ManConst0(pGia)->Value = 0; Gia_ManForEachCi( pGia, pObj, i ) pObj->Value = Mini_LutCreatePi(p); // create internal nodes diff --git a/src/aig/gia/giaMuxes.c b/src/aig/gia/giaMuxes.c index c0414d14..7b3aa54c 100644 --- a/src/aig/gia/giaMuxes.c +++ b/src/aig/gia/giaMuxes.c @@ -20,6 +20,7 @@ #include "gia.h" #include "misc/util/utilNam.h" +#include "misc/util/utilTruth.h" #include "misc/vec/vecWec.h" #include "misc/vec/vecHsh.h" @@ -157,12 +158,12 @@ Gia_Man_t * Gia_ManDupMuxes( Gia_Man_t * p, int Limit ) SeeAlso [] ***********************************************************************/ -Gia_Man_t * Gia_ManDupNoMuxes( Gia_Man_t * p ) +Gia_Man_t * Gia_ManDupNoMuxes( Gia_Man_t * p, int fSkipBufs ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i; - assert( p->pMuxes != NULL ); + assert( p->pMuxes != NULL || Gia_ManXorNum(p) ); // start the new manager pNew = Gia_ManStart( 5000 ); pNew->pName = Abc_UtilStrsav( p->pName ); @@ -176,7 +177,7 @@ Gia_Man_t * Gia_ManDupNoMuxes( Gia_Man_t * p ) else if ( Gia_ObjIsCo(pObj) ) pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) ); else if ( Gia_ObjIsBuf(pObj) ) - pObj->Value = Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); + pObj->Value = fSkipBufs ? Gia_ObjFanin0Copy(pObj) : Gia_ManAppendBuf( pNew, Gia_ObjFanin0Copy(pObj) ); else if ( Gia_ObjIsMuxId(p, i) ) pObj->Value = Gia_ManHashMux( pNew, Gia_ObjFanin2Copy(p, pObj), Gia_ObjFanin1Copy(pObj), Gia_ObjFanin0Copy(pObj) ); else if ( Gia_ObjIsXor(pObj) ) @@ -207,7 +208,7 @@ Gia_Man_t * Gia_ManDupMuxesTest( Gia_Man_t * p ) { Gia_Man_t * pNew, * pNew2; pNew = Gia_ManDupMuxes( p, 2 ); - pNew2 = Gia_ManDupNoMuxes( pNew ); + pNew2 = Gia_ManDupNoMuxes( pNew, 0 ); Gia_ManPrintStats( p, NULL ); Gia_ManPrintStats( pNew, NULL ); Gia_ManPrintStats( pNew2, NULL ); @@ -287,7 +288,7 @@ Gia_Man_t * Gia_ManDupMuxRestructure( Gia_Man_t * p ) { Gia_Man_t * pTemp, * pNew = Gia_ManDupMuxes( p, 2 ); pNew = Gia_ManMuxRestructure( pTemp = pNew ); Gia_ManStop( pTemp ); - pNew = Gia_ManDupNoMuxes( pTemp = pNew ); Gia_ManStop( pTemp ); + pNew = Gia_ManDupNoMuxes( pTemp = pNew, 0 ); Gia_ManStop( pTemp ); return pNew; } @@ -980,6 +981,186 @@ void Gia_ManProfileStructures( Gia_Man_t * p, int nLimit, int fVerbose ) } } +/**Function************************************************************* + + Synopsis [Circuit restructuring.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManMarkTfi_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) +{ + if ( Gia_ObjIsTravIdCurrent(p, pObj) ) + return; + Gia_ObjSetTravIdCurrent(p, pObj); + if ( !Gia_ObjIsAnd(pObj) ) + return; + Gia_ManMarkTfi_rec( p, Gia_ObjFanin0(pObj) ); + Gia_ManMarkTfi_rec( p, Gia_ObjFanin1(pObj) ); +} +Vec_Int_t * Gia_ManFindSharedInputs( Gia_Man_t * p ) +{ + Gia_Obj_t * pObj, * pObj2; int i, k, Value; + Vec_Int_t * vRes = Vec_IntStart( Gia_ManCiNum(p) ); + Gia_ManForEachCo( p, pObj, i ) + { + Gia_ManIncrementTravId( p ); + Gia_ManMarkTfi_rec( p, Gia_ObjFanin0(pObj) ); + Gia_ManForEachCi( p, pObj2, k ) + if ( Gia_ObjIsTravIdCurrent(p, pObj2) ) + Vec_IntAddToEntry( vRes, k, 1 ); + } + k = 0; + Vec_IntForEachEntry( vRes, Value, i ) + if ( Value == Gia_ManCoNum(p) ) + Vec_IntWriteEntry( vRes, k++, i ); + Vec_IntShrink( vRes, k ); + //printf( "Found %d candidate inputs.\n", Vec_IntSize(vRes) ); + if ( Vec_IntSize(vRes) == 0 || Vec_IntSize(vRes) > 10 ) + Vec_IntFreeP(&vRes); + return vRes; +} +Vec_Wec_t * Gia_ManFindCofs( Gia_Man_t * p, Vec_Int_t * vRes, Gia_Man_t ** ppNew ) +{ + Gia_Obj_t * pObj; + Vec_Wec_t * vCofs = Vec_WecStart( 1 << Vec_IntSize(vRes) ); + int Value, i, m, nMints = 1 << Vec_IntSize(vRes); + Gia_Man_t * pNew = Gia_ManStart( Gia_ManObjNum(p) ); + pNew->pName = Abc_UtilStrsav( p->pName ); + pNew->pSpec = Abc_UtilStrsav( p->pSpec ); + Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); + Gia_ManHashAlloc( pNew ); + Gia_ManFillValue( p ); + Gia_ManConst0(p)->Value = 0; + assert( Vec_IntSize(vRes) < Gia_ManCiNum(p) ); + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi(pNew); + for ( m = 0; m < nMints; m++ ) + { + Vec_Int_t * vLayer = Vec_WecEntry( vCofs, m ); + Vec_IntForEachEntry( vRes, Value, i ) + Gia_ManCi(p, Value)->Value = (unsigned)((m >> i) & 1); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachCo( p, pObj, i ) + Vec_IntPush( vLayer, Gia_ObjFanin0Copy(pObj) ); + assert( Vec_IntSize(vLayer) == Gia_ManCoNum(p) ); + //printf( "%3d : ", m ); Vec_IntPrint( vLayer ); + } + if ( ppNew != NULL ) + *ppNew = pNew; + return vCofs; +} +Vec_Int_t * Gia_ManFindEquivClasses( Vec_Wec_t * vCofs ) +{ + Vec_Int_t * vVec; int i, k, Lev; + Vec_Int_t * vMap = Vec_IntAlloc( Vec_WecSize(vCofs) ); + Vec_Int_t * vUnique = Vec_IntAlloc( Vec_WecSize(vCofs) ); + Vec_WecForEachLevel( vCofs, vVec, i ) + { + Vec_IntForEachEntry( vUnique, Lev, k ) + if ( Vec_IntEqual(vVec, Vec_WecEntry(vCofs, Lev)) ) + break; + Vec_IntPush( vMap, k ); + if ( k == Vec_IntSize(vUnique) ) + Vec_IntPush( vUnique, i ); + } + //printf( "Found %d equiv clasess.\n", Vec_IntSize(vUnique) ); + //Vec_IntPrint( vUnique ); + Vec_IntFree( vUnique ); + assert( Vec_IntSize(vMap) == Vec_WecSize(vCofs) ); + //Vec_IntPrint( vMap ); + return vMap; +} +int Gia_ManFindMuxTree_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData, int Shift ) +{ + int iLit0, iLit1; + if ( nCtrl-- == 0 ) + return Vec_IntEntry( vData, Shift ); + iLit0 = Gia_ManFindMuxTree_rec( pNew, pCtrl, nCtrl, vData, Shift ); + iLit1 = Gia_ManFindMuxTree_rec( pNew, pCtrl, nCtrl, vData, Shift + (1<<nCtrl) ); + return Gia_ManHashMux( pNew, pCtrl[nCtrl], iLit1, iLit0 ); +} +void Gia_ManFindDerive( Gia_Man_t * pNew, int nOuts, Vec_Int_t * vIns, Vec_Wec_t * vCofs, Vec_Int_t * vMap ) +{ + extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); + Vec_Int_t * vMemory = Vec_IntAlloc( 1 << 16 ); + Vec_Int_t * vLeaves = Vec_IntAlloc( 100 ); + Vec_Int_t * vUsed = Vec_IntStart( Vec_WecSize(vCofs) ); + Vec_Int_t * vBits = Vec_IntAlloc( 10 ); + Vec_Int_t * vData = Vec_IntAlloc( Vec_WecSize(vCofs) ); + int nWords = Abc_TtWordNum(Vec_IntSize(vIns)); + word * pTruth = ABC_ALLOC( word, nWords ); + int nValues = Vec_IntFindMax(vMap)+1; + int i, k, Value, nBits = Abc_Base2Log(nValues); + assert( nBits < Vec_IntSize(vIns) ); + assert( Vec_IntSize(vMap) == Vec_WecSize(vCofs) ); + assert( Vec_IntSize(vMap) == (1 << Vec_IntSize(vIns)) ); + Vec_IntForEachEntry( vIns, Value, i ) + Vec_IntPush( vLeaves, Gia_ObjToLit(pNew, Gia_ManCi(pNew, Value)) ); + for ( i = 0; i < nBits; i++ ) + { + Abc_TtClear( pTruth, nWords ); + Vec_IntForEachEntry( vMap, Value, k ) + if ( (Value >> i) & 1 ) + Abc_TtSetBit( pTruth, k ); + if ( nBits < 6 ) + pTruth[0] = Abc_Tt6Stretch( pTruth[0], Vec_IntSize(vIns) ); + Vec_IntPush( vBits, Kit_TruthToGia(pNew, (unsigned*)pTruth, Vec_IntSize(vIns), vMemory, vLeaves, 1) ); + //printf( "Bit %d : ", i ); Dau_DsdPrintFromTruth( pTruth, Vec_IntSize(vIns) ); + } + for ( i = 0; i < nValues; i++ ) + { + int Cof = Vec_IntFind(vMap, i); + assert( Cof >= 0 && Cof < Vec_WecSize(vCofs) ); + Vec_IntWriteEntry( vUsed, Cof, 1 ); + } + for ( i = 0; i < nOuts; i++ ) + { + Vec_Int_t * vLevel; + Vec_IntClear( vData ); + Vec_WecForEachLevel( vCofs, vLevel, k ) + if ( Vec_IntEntry(vUsed, k) ) + Vec_IntPush( vData, Vec_IntEntry(vLevel, i) ); + while ( Vec_IntSize(vData) < (1 << nBits) ) + Vec_IntPush( vData, 0 ); + assert( Vec_IntSize(vData) == (1 << nBits) ); + assert( Vec_IntSize(vBits) == nBits ); + Value = Gia_ManFindMuxTree_rec( pNew, Vec_IntArray(vBits), Vec_IntSize(vBits), vData, 0 ); + Gia_ManAppendCo( pNew, Value ); + } + ABC_FREE( pTruth ); + Vec_IntFree( vUsed ); + Vec_IntFree( vBits ); + Vec_IntFree( vData ); + Vec_IntFree( vLeaves ); + Vec_IntFree( vMemory ); +} +Gia_Man_t * Gia_ManCofStructure( Gia_Man_t * p ) +{ + Gia_Man_t * pNew = NULL; + Vec_Int_t * vIns = Gia_ManFindSharedInputs( p ); + Vec_Wec_t * vCfs = vIns ? Gia_ManFindCofs( p, vIns, &pNew ) : NULL; + Vec_Int_t * vMap = vCfs ? Gia_ManFindEquivClasses( vCfs ) : NULL; + if ( vMap && Abc_Base2Log(Vec_IntFindMax(vMap)+1) < Vec_IntSize(vIns) ) + { + Gia_Man_t * pTemp; + Gia_ManFindDerive( pNew, Gia_ManCoNum(p), vIns, vCfs, vMap ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + } + else + Gia_ManStopP( &pNew ); + Vec_WecFreeP( &vCfs ); + Vec_IntFreeP( &vMap ); + Vec_IntFreeP( &vIns ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaQbf.c b/src/aig/gia/giaQbf.c index f32db0a4..ac6fb22c 100644 --- a/src/aig/gia/giaQbf.c +++ b/src/aig/gia/giaQbf.c @@ -23,6 +23,7 @@ #include "sat/bsat/satStore.h" #include "misc/extra/extra.h" #include "sat/glucose/AbcGlucose.h" +#include "misc/util/utilTruth.h" ABC_NAMESPACE_IMPL_START @@ -184,6 +185,202 @@ Gia_Man_t * Gia_GenQbfMiter( Gia_Man_t * p, int nFrames, int nLutNum, int nLutSi return pNew; } + +/**Function************************************************************* + + Synopsis [Generate miter for the encoding problem.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_Gen2CreateMux_rec( Gia_Man_t * pNew, int * pCtrl, int nCtrl, Vec_Int_t * vData, int Shift ) +{ + int iLit0, iLit1; + if ( nCtrl == 0 ) + return Vec_IntEntry( vData, Shift ); + iLit0 = Gia_Gen2CreateMux_rec( pNew, pCtrl, nCtrl-1, vData, Shift ); + iLit1 = Gia_Gen2CreateMux_rec( pNew, pCtrl, nCtrl-1, vData, Shift + (1<<(nCtrl-1)) ); + return Gia_ManHashMux( pNew, pCtrl[nCtrl-1], iLit1, iLit0 ); +} +Vec_Int_t * Gia_Gen2CreateMuxes( Gia_Man_t * pNew, int nLutSize, int nLutNum, Vec_Int_t * vPLits, Vec_Int_t * vXLits ) +{ + Vec_Int_t * vLits = Vec_IntAlloc( nLutNum ); + int i, iMux; + // add MUXes for each group of flops + assert( Vec_IntSize(vPLits) == nLutNum * (1 << nLutSize) ); + assert( Vec_IntSize(vXLits) == nLutSize ); + for ( i = 0; i < nLutNum; i++ ) + { + iMux = Gia_Gen2CreateMux_rec( pNew, Vec_IntArray(vXLits), nLutSize, vPLits, i * (1 << nLutSize) ); + Vec_IntPush( vLits, iMux ); + } + return vLits; +} +Gia_Man_t * Gia_Gen2CreateMiter( int nLutSize, int nLutNum ) +{ + // |<-- PVars(0)-->|...|<-- PVars(nLutNum-1)-->|<-- XVars-->|<-- YVars-->| + Vec_Int_t * vPLits = Vec_IntAlloc( nLutNum * (1 << nLutSize) ); + Vec_Int_t * vXLits = Vec_IntAlloc( nLutSize ); + Vec_Int_t * vYLits = Vec_IntAlloc( nLutSize ); + Vec_Int_t * vXYLits = Vec_IntAlloc( nLutSize ); + Vec_Int_t * vXRes, * vYRes, * vXYRes; + Vec_Int_t * vXYRes2 = Vec_IntAlloc( 2 * nLutNum ); + Gia_Man_t * pTemp, * pNew = Gia_ManStart( 1000 ); int i, k, v, Cond, Res; + pNew->pName = Abc_UtilStrsav( "homoqbf" ); + Gia_ManHashAlloc( pNew ); + for ( i = 0; i < nLutNum * (1 << nLutSize); i++ ) + Vec_IntPush( vPLits, Gia_ManAppendCi(pNew) ); + for ( i = 0; i < nLutSize; i++ ) + Vec_IntPush( vXLits, Gia_ManAppendCi(pNew) ); + for ( i = 0; i < nLutSize; i++ ) + Vec_IntPush( vYLits, Gia_ManAppendCi(pNew) ); + for ( i = 0; i < nLutSize; i++ ) + Vec_IntPush( vXYLits, Abc_LitNot(Gia_ManHashAnd(pNew, Vec_IntEntry(vXLits, i), Vec_IntEntry(vYLits, i))) ); + vXRes = Gia_Gen2CreateMuxes( pNew, nLutSize, nLutNum, vPLits, vXLits ); + vYRes = Gia_Gen2CreateMuxes( pNew, nLutSize, nLutNum, vPLits, vYLits ); + vXYRes = Gia_Gen2CreateMuxes( pNew, nLutSize, nLutNum, vPLits, vXYLits ); + for ( i = 0; i < nLutNum; i++ ) + { + Vec_IntPush( vXYRes2, Vec_IntEntry(vXYRes, i) ); + Vec_IntPush( vXYRes2, Abc_LitNot(Gia_ManHashAnd(pNew, Vec_IntEntry(vXRes, i), Vec_IntEntry(vYRes, i))) ); + } + Res = Gia_ManHashDualMiter( pNew, vXYRes2 ); + // uniqueness of codes + for ( i = 0; i < (1 << nLutSize); i++ ) + { + Vec_Int_t * vCondA = Vec_IntAlloc( nLutNum ); + Vec_Int_t * vCondB = Vec_IntAlloc( nLutNum ); + for ( v = 0; v < nLutNum; v++ ) + Vec_IntPush( vCondA, Vec_IntEntry(vPLits, v*(1 << nLutSize)+i) ); + for ( k = i+1; k < (1 << nLutSize); k++ ) + { + Vec_IntClear( vCondB ); + for ( v = 0; v < nLutNum; v++ ) + { + Vec_IntPush( vCondB, Vec_IntEntry(vCondA, v) ); + Vec_IntPush( vCondB, Vec_IntEntry(vPLits, v*(1 << nLutSize)+k) ); + } + Cond = Gia_ManHashDualMiter( pNew, vCondB ); + Res = Gia_ManHashOr( pNew, Res, Abc_LitNot(Cond) ); + } + Vec_IntFree( vCondA ); + Vec_IntFree( vCondB ); + } + Gia_ManAppendCo( pNew, Abc_LitNot(Res) ); + Gia_ManHashStop( pNew ); + Vec_IntFree( vPLits ); + Vec_IntFree( vXLits ); + Vec_IntFree( vYLits ); + Vec_IntFree( vXYLits ); + Vec_IntFree( vXRes ); + Vec_IntFree( vYRes ); + Vec_IntFree( vXYRes ); + Vec_IntFree( vXYRes2 ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + printf( "Generated QBF miter with %d parameters, %d functional variables, and %d AIG nodes.\n", + nLutNum * (1 << nLutSize), 2*nLutSize, Gia_ManAndNum(pNew) ); + return pNew; +} +int Gia_Gen2CodeOne( int nLutSize, int nLutNum, Vec_Int_t * vCode, int x ) +{ + int k, Code = 0; + for ( k = 0; k < nLutNum; k++ ) + if ( Vec_IntEntry(vCode, k*(1 << nLutSize)+x) ) + Code |= (1 << k); + return Code; +} +word * Gia_Gen2CodeOneP( int nLutSize, int nLutNum, Vec_Int_t * vCode, int x ) +{ + word * pRes = ABC_CALLOC( word, Abc_Bit6WordNum(nLutNum) ); + int k; + for ( k = 0; k < nLutNum; k++ ) + if ( Vec_IntEntry(vCode, k*(1 << nLutSize)+x) ) + Abc_InfoSetBit( (unsigned *)pRes, k ); + return pRes; +} +void Gia_Gen2CodePrint( int nLutSize, int nLutNum, Vec_Int_t * vCode ) +{ + // |<-- PVars(0)-->|...|<-- PVars(nLutNum-1)-->| + int i, n, nPairs = 16; + printf( "%d-input %d-output code table:\n", nLutSize, nLutNum ); + for ( i = 0; i < (1 << nLutSize); i++ ) + { + word * CodeX = Gia_Gen2CodeOneP( nLutSize, nLutNum, vCode, i ); + printf( "%3d ", i ); + Extra_PrintBinary( stdout, (unsigned *)&i, nLutSize ); + printf( " --> " ); + if ( nLutNum <= 16 ) + printf( "%5d ", (int)CodeX[0] ); + Extra_PrintBinary( stdout, (unsigned *)CodeX, nLutNum ); + printf( "\n" ); + ABC_FREE( CodeX ); + } + // create several different pairs + srand( time(NULL) ); + printf( "Simulation of the encoding with %d random pairs:\n", nPairs ); + for ( n = 0; n < nPairs; n++ ) + { + unsigned MaskIn = Abc_InfoMask( nLutSize ); + int NumX = 0, NumY = 0, NumXY, nWords = Abc_Bit6WordNum(nLutNum); + word * CodeX, * CodeY, * CodeXY; + word * CodeXCodeY = ABC_CALLOC( word, nWords ); + while ( NumX == NumY ) + { + NumX = rand() % (1 << nLutSize); + NumY = rand() % (1 << nLutSize); + NumXY = MaskIn & ~(NumX & NumY); + } + CodeX = Gia_Gen2CodeOneP( nLutSize, nLutNum, vCode, NumX ); + CodeY = Gia_Gen2CodeOneP( nLutSize, nLutNum, vCode, NumY ); + CodeXY = Gia_Gen2CodeOneP( nLutSize, nLutNum, vCode, NumXY ); + Abc_TtAnd( CodeXCodeY, CodeX, CodeY, nWords, 1 ); + if ( nLutNum < 64*nWords ) + CodeXCodeY[nWords-1] &= Abc_Tt6Mask(nLutNum % 64); + + printf( "%2d :", n ); + printf( " x =%3d ", NumX ); + Extra_PrintBinary( stdout,(unsigned *) &NumX, nLutSize ); + printf( " y =%3d ", NumY ); + Extra_PrintBinary( stdout, (unsigned *)&NumY, nLutSize ); + printf( " nand =%3d ", NumXY ); + Extra_PrintBinary( stdout, (unsigned *)&NumXY, nLutSize ); + printf( " " ); + + printf( " c(x) = " ); + Extra_PrintBinary( stdout, (unsigned *)CodeX, nLutNum ); + printf( " c(y) = " ); + Extra_PrintBinary( stdout, (unsigned *)CodeY, nLutNum ); + printf( " c(nand) = " ); + Extra_PrintBinary( stdout, (unsigned *)CodeXY, nLutNum ); + printf( " nand(c(x),c(y)) = " ); + Extra_PrintBinary( stdout, (unsigned *)CodeXCodeY, nLutNum ); + printf( " " ); + + printf( "%s", Abc_TtEqual(CodeXCodeY, CodeXY, nWords) ? "yes" : "no" ); + printf( "\n" ); + + ABC_FREE( CodeX ); + ABC_FREE( CodeY ); + ABC_FREE( CodeXY ); + ABC_FREE( CodeXCodeY ); + } +} +void Gia_Gen2CodeTest() +{ + int i, nLutSize = 1, nLutNum = 2; + Vec_Int_t * vCode = Vec_IntAlloc( (1 << nLutSize) * nLutNum ); + srand( time(NULL) ); + for ( i = 0; i < (1 << nLutSize) * nLutNum; i++ ) + Vec_IntPush( vCode, rand() & 1 ); + Gia_Gen2CodePrint( nLutSize, nLutNum, vCode ); + Vec_IntFree( vCode ); +} + /**Function************************************************************* Synopsis [Naive way to enumerate SAT assignments.] @@ -632,7 +829,7 @@ void Gia_QbfLearnConstraint( Qbf_Man_t * p, Vec_Int_t * vValues ) SeeAlso [] ***********************************************************************/ -int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, int nTimeOut, int fGlucose, int fVerbose ) +int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, int nTimeOut, int nEncVars, int fGlucose, int fVerbose ) { Qbf_Man_t * p = Gia_QbfAlloc( pGia, nPars, fGlucose, fVerbose ); Gia_Man_t * pCof; @@ -679,6 +876,12 @@ int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, i assert( Vec_IntSize(p->vValues) == nPars ); Vec_IntPrintBinary( p->vValues ); printf( " Statistics: 0=%d 1=%d\n", nZeros, Vec_IntSize(p->vValues) - nZeros ); + if ( nEncVars ) + { + int nBits = Vec_IntSize(p->vValues)/(1 << nEncVars); + assert( Vec_IntSize(p->vValues) == (1 << nEncVars) * nBits ); + Gia_Gen2CodePrint( nEncVars, nBits, p->vValues ); + } } if ( RetValue == -1 && nTimeOut && (Abc_Clock() - p->clkStart)/CLOCKS_PER_SEC >= nTimeOut ) printf( "The problem timed out after %d sec. ", nTimeOut ); diff --git a/src/aig/gia/giaSim.c b/src/aig/gia/giaSim.c index 564be76c..001bd8ac 100644 --- a/src/aig/gia/giaSim.c +++ b/src/aig/gia/giaSim.c @@ -1223,642 +1223,6 @@ int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 ) - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Vec_Wrd_t * Gia_ManSimPatGenRandom( int nWords ) -{ - Vec_Wrd_t * vSims = Vec_WrdAlloc( nWords ); int i; - for ( i = 0; i < nWords; i++ ) - Vec_WrdPush( vSims, Gia_ManRandomW(0) ); - return vSims; -} -void Gia_ManSimPatAssignInputs( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsIn ) -{ - int i, Id; - assert( Vec_WrdSize(vSims) == nWords * Gia_ManObjNum(p) ); - assert( Vec_WrdSize(vSimsIn) == nWords * Gia_ManCiNum(p) ); - Gia_ManForEachCiId( p, Id, i ) - memcpy( Vec_WrdEntryP(vSims, Id*nWords), Vec_WrdEntryP(vSimsIn, i*nWords), sizeof(word)*nWords ); -} -static inline void Gia_ManSimPatSimAnd( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims ) -{ - word pComps[2] = { 0, ~(word)0 }; - word Diff0 = pComps[Gia_ObjFaninC0(pObj)]; - word Diff1 = pComps[Gia_ObjFaninC1(pObj)]; - word * pSims = Vec_WrdArray(vSims); - word * pSims0 = pSims + nWords*Gia_ObjFaninId0(pObj, i); - word * pSims1 = pSims + nWords*Gia_ObjFaninId1(pObj, i); - word * pSims2 = pSims + nWords*i; int w; - for ( w = 0; w < nWords; w++ ) - pSims2[w] = (pSims0[w] ^ Diff0) & (pSims1[w] ^ Diff1); -} -static inline void Gia_ManSimPatSimPo( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims ) -{ - word pComps[2] = { 0, ~(word)0 }; - word Diff0 = pComps[Gia_ObjFaninC0(pObj)]; - word * pSims = Vec_WrdArray(vSims); - word * pSims0 = pSims + nWords*Gia_ObjFaninId0(pObj, i); - word * pSims2 = pSims + nWords*i; int w; - for ( w = 0; w < nWords; w++ ) - pSims2[w] = (pSims0[w] ^ Diff0); -} -Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * pGia ) -{ - Gia_Obj_t * pObj; - int i, nWords = Vec_WrdSize(pGia->vSimsPi) / Gia_ManCiNum(pGia); - Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords ); - assert( Vec_WrdSize(pGia->vSimsPi) % Gia_ManCiNum(pGia) == 0 ); - Gia_ManSimPatAssignInputs( pGia, nWords, vSims, pGia->vSimsPi ); - Gia_ManForEachAnd( pGia, pObj, i ) - Gia_ManSimPatSimAnd( pGia, i, pObj, nWords, vSims ); - Gia_ManForEachCo( pGia, pObj, i ) - Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); - return vSims; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/\ -Vec_Wrd_t * Gia_ManSimCombine( int nInputs, Vec_Wrd_t * vBase, Vec_Wrd_t * vAddOn, int nWordsUse ) -{ - int nWordsBase = Vec_WrdSize(vBase) / nInputs; - int nWordsAddOn = Vec_WrdSize(vAddOn) / nInputs; int i, w; - Vec_Wrd_t * vSimsIn = Vec_WrdAlloc( nInputs * (nWordsBase + nWordsUse) ); - assert( Vec_WrdSize(vBase) % nInputs == 0 ); - assert( Vec_WrdSize(vAddOn) % nInputs == 0 ); - assert( nWordsUse <= nWordsAddOn ); - for ( i = 0; i < nInputs; i++ ) - { - word * pSimsB = Vec_WrdEntryP( vBase, i * nWordsBase ); - word * pSimsA = Vec_WrdEntryP( vAddOn, i * nWordsAddOn ); - for ( w = 0; w < nWordsBase; w++ ) - Vec_WrdPush( vSimsIn, pSimsB[w] ); - for ( w = 0; w < nWordsUse; w++ ) - Vec_WrdPush( vSimsIn, pSimsA[w] ); - } - assert( Vec_WrdSize(vSimsIn) == Vec_WrdCap(vSimsIn) ); - return vSimsIn; -} -int Gia_ManSimBitPackOne( int nWords, Vec_Wrd_t * vSimsIn, Vec_Wrd_t * vSimsCare, int iPat, int * pLits, int nLits ) -{ - word * pSimsI, * pSimsC; int i, k; - for ( i = 0; i < iPat; i++ ) - { - for ( k = 0; k < nLits; k++ ) - { - int iVar = Abc_Lit2Var( pLits[k] ); - pSimsI = Vec_WrdEntryP( vSimsIn, nWords * iVar ); - pSimsC = Vec_WrdEntryP( vSimsCare, nWords * iVar ); - if ( Abc_TtGetBit(pSimsC, i) && (Abc_TtGetBit(pSimsI, i) == Abc_LitIsCompl(pLits[k])) ) - break; - } - if ( k == nLits ) - break; - } - for ( k = 0; k < nLits; k++ ) - { - int iVar = Abc_Lit2Var( pLits[k] ); - pSimsI = Vec_WrdEntryP( vSimsIn, nWords * iVar ); - pSimsC = Vec_WrdEntryP( vSimsCare, nWords * iVar ); - if ( !Abc_TtGetBit(pSimsC, i) && Abc_TtGetBit(pSimsI, i) == Abc_LitIsCompl(pLits[k]) ) - Abc_TtXorBit( pSimsI, i ); - Abc_TtSetBit( pSimsC, i ); - assert( Abc_TtGetBit(pSimsC, i) && (Abc_TtGetBit(pSimsI, i) != Abc_LitIsCompl(pLits[k])) ); - } - return (int)(i == iPat); -} -Vec_Wrd_t * Gia_ManSimBitPacking( Gia_Man_t * p, Vec_Int_t * vCexStore, int nCexes ) -{ - int c, iCur = 0, iPat = 0; - int nWordsMax = Abc_Bit6WordNum( nCexes ); - Vec_Wrd_t * vSimsIn = Gia_ManSimPatGenRandom( Gia_ManCiNum(p) * nWordsMax ); - Vec_Wrd_t * vSimsCare = Vec_WrdStart( Gia_ManCiNum(p) * nWordsMax ); - Vec_Wrd_t * vSimsRes = NULL; - for ( c = 0; c < nCexes; c++ ) - { - int Out = Vec_IntEntry( vCexStore, iCur++ ); - int Size = Vec_IntEntry( vCexStore, iCur++ ); - iPat += Gia_ManSimBitPackOne( nWordsMax, vSimsIn, vSimsCare, iPat, Vec_IntEntryP(vCexStore, iCur), Size ); - iCur += Size; - assert( iPat <= nCexes ); - Out = 0; - } - printf( "Compressed %d CEXes into %d test patterns.\n", nCexes, iPat ); - assert( iCur == Vec_IntSize(vCexStore) ); - vSimsRes = Gia_ManSimCombine( Gia_ManCiNum(p), p->vSimsPi, vSimsIn, Abc_Bit6WordNum(iPat+1) ); - printf( "Combined %d words of the original info with %d words of additional info.\n", - Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p), Abc_Bit6WordNum(iPat+1) ); - Vec_WrdFree( vSimsIn ); - Vec_WrdFree( vSimsCare ); - return vSimsRes; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ManSimPatHashPatterns( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, int * pnC0, int * pnC1 ) -{ - Gia_Obj_t * pObj; - int i, nUnique; - Vec_Mem_t * vStore; - vStore = Vec_MemAlloc( nWords, 12 ); // 2^12 N-word entries per page - Vec_MemHashAlloc( vStore, 1 << 12 ); - Gia_ManForEachCand( p, pObj, i ) - { - word * pSim = Vec_WrdEntryP(vSims, i*nWords); - if ( pnC0 && Abc_TtIsConst0(pSim, nWords) ) - (*pnC0)++; - if ( pnC1 && Abc_TtIsConst1(pSim, nWords) ) - (*pnC1)++; - Vec_MemHashInsert( vStore, pSim ); - } - nUnique = Vec_MemEntryNum( vStore ); - Vec_MemHashFree( vStore ); - Vec_MemFree( vStore ); - return nUnique; -} -Gia_Man_t * Gia_ManSimPatGenMiter( Gia_Man_t * p, Vec_Wrd_t * vSims ) -{ - Gia_Man_t * pNew; - Gia_Obj_t * pObj; - int i, nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(p); - pNew = Gia_ManStart( Gia_ManObjNum(p) + Gia_ManCoNum(p) ); - Gia_ManHashStart( pNew ); - Gia_ManConst0(p)->Value = 0; - Gia_ManForEachCi( p, pObj, i ) - pObj->Value = Gia_ManAppendCi( pNew ); - Gia_ManForEachAnd( p, pObj, i ) - pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); - Gia_ManForEachAnd( p, pObj, i ) - { - word * pSim = Vec_WrdEntryP(vSims, i*nWords); - if ( Abc_TtIsConst0(pSim, nWords) ) - Gia_ManAppendCo( pNew, Abc_LitNotCond(pObj->Value, 0) ); - if ( Abc_TtIsConst1(pSim, nWords) ) - Gia_ManAppendCo( pNew, Abc_LitNotCond(pObj->Value, 1) ); - } - Gia_ManHashStop( pNew ); - return pNew; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManSimPatWriteOne( FILE * pFile, word * pSim, int nWords ) -{ - int k, Digit, nDigits = nWords*16; - for ( k = 0; k < nDigits; k++ ) - { - Digit = (int)((pSim[k/16] >> ((k%16) * 4)) & 15); - if ( Digit < 10 ) - fprintf( pFile, "%d", Digit ); - else - fprintf( pFile, "%c", 'A' + Digit-10 ); - } - fprintf( pFile, "\n" ); -} -void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords ) -{ - int i, nNodes = Vec_WrdSize(vSimsIn) / nWords; - FILE * pFile = fopen( pFileName, "wb" ); - if ( pFile == NULL ) - { - printf( "Cannot open file \"%s\" for writing.\n", pFileName ); - return; - } - assert( Vec_WrdSize(vSimsIn) % nWords == 0 ); - for ( i = 0; i < nNodes; i++ ) - Gia_ManSimPatWriteOne( pFile, Vec_WrdEntryP(vSimsIn, i*nWords), nWords ); - fclose( pFile ); - printf( "Written %d words of simulation data.\n", nWords ); -} -int Gia_ManSimPatReadOne( char c ) -{ - int Digit = 0; - if ( c >= '0' && c <= '9' ) - Digit = c - '0'; - else if ( c >= 'A' && c <= 'F' ) - Digit = c - 'A' + 10; - else if ( c >= 'a' && c <= 'f' ) - Digit = c - 'a' + 10; - else assert( 0 ); - assert( Digit >= 0 && Digit < 16 ); - return Digit; -} -Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName ) -{ - Vec_Wrd_t * vSimsIn = NULL; - int c, nWords = -1, nChars = 0; word Num = 0; - FILE * pFile = fopen( pFileName, "rb" ); - if ( pFile == NULL ) - { - printf( "Cannot open file \"%s\" for reading.\n", pFileName ); - return NULL; - } - vSimsIn = Vec_WrdAlloc( 1000 ); - while ( (c = fgetc(pFile)) != EOF ) - { - if ( c == '\n' && nWords == -1 ) - nWords = Vec_WrdSize(vSimsIn); - if ( c == '\n' || c == '\r' || c == '\t' || c == ' ' ) - continue; - Num |= (word)Gia_ManSimPatReadOne((char)c) << (nChars * 4); - if ( ++nChars < 16 ) - continue; - Vec_WrdPush( vSimsIn, Num ); - nChars = 0; - Num = 0; - } - assert( Vec_WrdSize(vSimsIn) % nWords == 0 ); - fclose( pFile ); - printf( "Read %d words of simulation data.\n", nWords ); - return vSimsIn; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManSimProfile( Gia_Man_t * pGia ) -{ - Vec_Wrd_t * vSims = Gia_ManSimPatSim( pGia ); - int nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia); - int nC0s = 0, nC1s = 0, nUnique = Gia_ManSimPatHashPatterns( pGia, nWords, vSims, &nC0s, &nC1s ); - printf( "Simulating %d words leads to %d unique objects (%.2f %% out of %d), Const0 = %d. Const1 = %d.\n", - nWords, nUnique, 100.0*nUnique/Gia_ManCandNum(pGia), Gia_ManCandNum(pGia), nC0s, nC1s ); - Vec_WrdFree( vSims ); -} -void Gia_ManSimPat( Gia_Man_t * p, int nWords0, int fVerbose ) -{ - extern Vec_Int_t * Cbs2_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose ); - int i, Status, Counts[3] = {0}; - Gia_Man_t * pGia; - Vec_Wrd_t * vSimsIn = NULL; - Vec_Str_t * vStatus = NULL; - Vec_Int_t * vCexStore = NULL; - Vec_Wrd_t * vSims = Gia_ManSimPatSim( p ); - Gia_ManSimProfile( p ); - pGia = Gia_ManSimPatGenMiter( p, vSims ); - vCexStore = Cbs2_ManSolveMiterNc( pGia, 1000, &vStatus, 0 ); - Gia_ManStop( pGia ); - Vec_StrForEachEntry( vStatus, Status, i ) - { - assert( Status >= -1 && Status <= 1 ); - Counts[Status+1]++; - } - printf( "Total = %d : SAT = %d. UNSAT = %d. UNDEC = %d.\n", Counts[1]+Counts[2]+Counts[0], Counts[1], Counts[2], Counts[0] ); - if ( Counts[1] == 0 ) - printf( "There are no counter-examples. No need for more simulation.\n" ); - else - { - vSimsIn = Gia_ManSimBitPacking( p, vCexStore, Counts[1] ); - Vec_WrdFreeP( &p->vSimsPi ); - p->vSimsPi = vSimsIn; - Gia_ManSimProfile( p ); - } - Vec_StrFree( vStatus ); - Vec_IntFree( vCexStore ); - Vec_WrdFree( vSims ); -} - - - - - -typedef struct Gia_SimRsbMan_t_ Gia_SimRsbMan_t; -struct Gia_SimRsbMan_t_ -{ - Gia_Man_t * pGia; - Vec_Int_t * vTfo; - Vec_Int_t * vCands; - Vec_Int_t * vFanins; - Vec_Int_t * vFanins2; - Vec_Wrd_t * vSimsObj; - Vec_Wrd_t * vSimsObj2; - int nWords; - word * pFunc[3]; -}; - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Gia_SimRsbMan_t * Gia_SimRsbAlloc( Gia_Man_t * pGia ) -{ - Gia_SimRsbMan_t * p = ABC_CALLOC( Gia_SimRsbMan_t, 1 ); - p->pGia = pGia; - p->nWords = Vec_WrdSize(pGia->vSimsPi) / Gia_ManCiNum(pGia); assert( Vec_WrdSize(pGia->vSimsPi) % Gia_ManCiNum(pGia) == 0 ); - p->pFunc[0] = ABC_CALLOC( word, p->nWords ); - p->pFunc[1] = ABC_CALLOC( word, p->nWords ); - p->pFunc[2] = ABC_CALLOC( word, p->nWords ); - p->vTfo = Vec_IntAlloc( 1000 ); - p->vCands = Vec_IntAlloc( 1000 ); - p->vFanins = Vec_IntAlloc( 10 ); - p->vFanins2 = Vec_IntAlloc( 10 ); - p->vSimsObj = Gia_ManSimPatSim( pGia ); - p->vSimsObj2 = Vec_WrdStart( Vec_WrdSize(p->vSimsObj) ); - assert( p->nWords == Vec_WrdSize(p->vSimsObj) / Gia_ManObjNum(pGia) ); - Gia_ManStaticFanoutStart( pGia ); - return p; -} -void Gia_SimRsbFree( Gia_SimRsbMan_t * p ) -{ - Gia_ManStaticFanoutStop( p->pGia ); - Vec_IntFree( p->vTfo ); - Vec_IntFree( p->vCands ); - Vec_IntFree( p->vFanins ); - Vec_IntFree( p->vFanins2 ); - Vec_WrdFree( p->vSimsObj ); - Vec_WrdFree( p->vSimsObj2 ); - ABC_FREE( p->pFunc[0] ); - ABC_FREE( p->pFunc[1] ); - ABC_FREE( p->pFunc[2] ); - ABC_FREE( p ); -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_SimRsbTfo_rec( Gia_Man_t * p, int iObj, int iFanout, Vec_Int_t * vTfo ) -{ - int i, iFan; - if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) - return; - Gia_ObjSetTravIdCurrentId(p, iObj); - Gia_ObjForEachFanoutStaticId( p, iObj, iFan, i ) - if ( iFanout == -1 || iFan == iFanout ) - Gia_SimRsbTfo_rec( p, iFan, -1, vTfo ); - Vec_IntPush( vTfo, iObj ); -} -Vec_Int_t * Gia_SimRsbTfo( Gia_SimRsbMan_t * p, int iObj, int iFanout ) -{ - assert( iObj > 0 ); - Vec_IntClear( p->vTfo ); - Gia_ManIncrementTravId( p->pGia ); - Gia_SimRsbTfo_rec( p->pGia, iObj, iFanout, p->vTfo ); - assert( Vec_IntEntryLast(p->vTfo) == iObj ); - Vec_IntPop( p->vTfo ); - Vec_IntReverseOrder( p->vTfo ); - Vec_IntSort( p->vTfo, 0 ); - return p->vTfo; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -word * Gia_SimRsbFunc( Gia_SimRsbMan_t * p, int iObj, Vec_Int_t * vFanins, int fOnSet ) -{ - int nTruthWords = Abc_Truth6WordNum( Vec_IntSize(vFanins) ); - word * pTruth = ABC_CALLOC( word, nTruthWords ); - word * pFunc = Vec_WrdEntryP( p->vSimsObj, p->nWords*iObj ); - word * pFanins[16] = {NULL}; int s, b, iMint, i, iFanin; - assert( Vec_IntSize(vFanins) <= 16 ); - Vec_IntForEachEntry( vFanins, iFanin, i ) - pFanins[i] = Vec_WrdEntryP( p->vSimsObj, p->nWords*iFanin ); - for ( s = 0; s < 64*p->nWords; s++ ) - { - if ( !Abc_TtGetBit(p->pFunc[2], s) || !Abc_TtGetBit(pFunc, s) == fOnSet ) - continue; - iMint = 0; - for ( b = 0; b < Vec_IntSize(vFanins); b++ ) - if ( Abc_TtGetBit(pFanins[b], s) ) - iMint |= 1 << b; - Abc_TtSetBit( pTruth, iMint ); - } - return pTruth; -} -int Gia_SimRsbResubVerify( Gia_SimRsbMan_t * p, int iObj, Vec_Int_t * vFanins ) -{ - word * pTruth0 = Gia_SimRsbFunc( p, iObj, p->vFanins, 0 ); - word * pTruth1 = Gia_SimRsbFunc( p, iObj, p->vFanins, 1 ); - int Res = !Abc_TtIntersect( pTruth0, pTruth1, p->nWords, 0 ); - ABC_FREE( pTruth0 ); - ABC_FREE( pTruth1 ); - return Res; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline void Gia_SimRsbSimAndCareSet( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSims2 ) -{ - word pComps[2] = { 0, ~(word)0 }; - word Diff0 = pComps[Gia_ObjFaninC0(pObj)]; - word Diff1 = pComps[Gia_ObjFaninC1(pObj)]; - Vec_Wrd_t * vSims0 = Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) ? vSims2 : vSims; - Vec_Wrd_t * vSims1 = Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) ? vSims2 : vSims; - word * pSims0 = Vec_WrdEntryP( vSims0, nWords*Gia_ObjFaninId0(pObj, i) ); - word * pSims1 = Vec_WrdEntryP( vSims1, nWords*Gia_ObjFaninId1(pObj, i) ); - word * pSims2 = Vec_WrdEntryP( vSims2, nWords*i ); int w; - for ( w = 0; w < nWords; w++ ) - pSims2[w] = (pSims0[w] ^ Diff0) & (pSims1[w] ^ Diff1); -} -word * Gia_SimRsbCareSet( Gia_SimRsbMan_t * p, int iObj, Vec_Int_t * vTfo ) -{ - word * pSims = Vec_WrdEntryP( p->vSimsObj, p->nWords*iObj ); - word * pSims2 = Vec_WrdEntryP( p->vSimsObj2, p->nWords*iObj ); int iNode, i; - Abc_TtCopy( pSims2, pSims, p->nWords, 1 ); - Abc_TtClear( p->pFunc[2], p->nWords ); - Vec_IntForEachEntry( vTfo, iNode, i ) - { - Gia_Obj_t * pNode = Gia_ManObj(p->pGia, iNode); - if ( Gia_ObjIsAnd(pNode) ) - Gia_SimRsbSimAndCareSet( p->pGia, iNode, pNode, p->nWords, p->vSimsObj, p->vSimsObj2 ); - else if ( Gia_ObjIsCo(pNode) ) - { - word * pSimsA = Vec_WrdEntryP( p->vSimsObj, p->nWords*Gia_ObjFaninId0p(p->pGia, pNode) ); - word * pSimsB = Vec_WrdEntryP( p->vSimsObj2, p->nWords*Gia_ObjFaninId0p(p->pGia, pNode) ); - Abc_TtOrXor( p->pFunc[2], pSimsA, pSimsB, p->nWords ); - } - else assert( 0 ); - } - return p->pFunc[2]; -} - - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ObjSimCollect( Gia_SimRsbMan_t * p ) -{ - int i, k, iTemp, iFanout; - Vec_IntClear( p->vFanins2 ); - assert( Vec_IntSize(p->vFanins) > 0 ); - Vec_IntForEachEntry( p->vFanins, iTemp, i ) - { - Gia_Obj_t * pObj = Gia_ManObj( p->pGia, iTemp ); - if ( Gia_ObjIsAnd(pObj) && !Gia_ObjIsTravIdCurrentId( p->pGia, Gia_ObjFaninId0(pObj, iTemp) ) ) - Vec_IntPush( p->vFanins2, Gia_ObjFaninId0(pObj, iTemp) ); - if ( Gia_ObjIsAnd(pObj) && !Gia_ObjIsTravIdCurrentId( p->pGia, Gia_ObjFaninId1(pObj, iTemp) ) ) - Vec_IntPush( p->vFanins2, Gia_ObjFaninId1(pObj, iTemp) ); - Gia_ObjForEachFanoutStaticId( p->pGia, iTemp, iFanout, k ) - if ( Gia_ObjIsAnd(Gia_ManObj(p->pGia, iFanout)) && !Gia_ObjIsTravIdCurrentId( p->pGia, iFanout ) ) - Vec_IntPush( p->vFanins2, iFanout ); - } -} -Vec_Int_t * Gia_ObjSimCands( Gia_SimRsbMan_t * p, int iObj, int nCands ) -{ - assert( iObj > 0 ); - assert( Gia_ObjIsAnd(Gia_ManObj(p->pGia, iObj)) ); - Vec_IntClear( p->vCands ); - Vec_IntFill( p->vFanins, 1, iObj ); - while ( Vec_IntSize(p->vFanins) > 0 && Vec_IntSize(p->vCands) < nCands ) - { - int i, iTemp; - Vec_IntForEachEntry( p->vFanins, iTemp, i ) - Gia_ObjSetTravIdCurrentId( p->pGia, iTemp ); - Gia_ObjSimCollect( p ); // p->vFanins -> p->vFanins2 - Vec_IntAppend( p->vCands, p->vFanins2 ); - ABC_SWAP( Vec_Int_t *, p->vFanins, p->vFanins2 ); - } - assert( Vec_IntSize(p->vFanins) == 0 || Vec_IntSize(p->vCands) >= nCands ); - if ( Vec_IntSize(p->vCands) > nCands ) - Vec_IntShrink( p->vCands, nCands ); - return p->vCands; -} - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int Gia_ObjSimRsb( Gia_SimRsbMan_t * p, int iObj, int nCands, int fVerbose, int * pnBufs, int * pnInvs ) -{ - int i, iCand, RetValue = 0; - Vec_Int_t * vTfo = Gia_SimRsbTfo( p, iObj, -1 ); - word * pCareSet = Gia_SimRsbCareSet( p, iObj, vTfo ); - word * pFunc = Vec_WrdEntryP( p->vSimsObj, p->nWords*iObj ); - Vec_Int_t * vCands = Gia_ObjSimCands( p, iObj, nCands ); - Abc_TtAndSharp( p->pFunc[0], pCareSet, pFunc, p->nWords, 1 ); - Abc_TtAndSharp( p->pFunc[1], pCareSet, pFunc, p->nWords, 0 ); - -/* -printf( "Considering node %d with %d candidates:\n", iObj, Vec_IntSize(vCands) ); -Vec_IntPrint( vTfo ); -Vec_IntPrint( vCands ); -Extra_PrintBinary( stdout, (unsigned *)pCareSet, 64 ); printf( "\n" ); -Extra_PrintBinary( stdout, (unsigned *)pFunc, 64 ); printf( "\n" ); -Extra_PrintBinary( stdout, (unsigned *)p->pFunc[0], 64 ); printf( "\n" ); -Extra_PrintBinary( stdout, (unsigned *)p->pFunc[1], 64 ); printf( "\n" ); -*/ - Vec_IntForEachEntry( vCands, iCand, i ) - { - word * pDiv = Vec_WrdEntryP( p->vSimsObj, p->nWords*iCand ); - if ( !Abc_TtIntersect(pDiv, p->pFunc[0], p->nWords, 0) && - !Abc_TtIntersect(pDiv, p->pFunc[1], p->nWords, 1) ) - { (*pnBufs)++; if ( fVerbose ) printf( "Level %3d : %d = buf(%d)\n", Gia_ObjLevelId(p->pGia, iObj), iObj, iCand ); RetValue = 1; } - if ( !Abc_TtIntersect(pDiv, p->pFunc[0], p->nWords, 1) && - !Abc_TtIntersect(pDiv, p->pFunc[1], p->nWords, 0) ) - { (*pnInvs)++; if ( fVerbose ) printf( "Level %3d : %d = inv(%d)\n", Gia_ObjLevelId(p->pGia, iObj), iObj, iCand ); RetValue = 1; } - } - return RetValue; -} - -int Gia_ManSimRsb( Gia_Man_t * pGia, int nCands, int fVerbose ) -{ - Gia_Obj_t * pObj; int iObj, nCount = 0, nBufs = 0, nInvs = 0; - Gia_SimRsbMan_t * p = Gia_SimRsbAlloc( pGia ); - assert( pGia->vSimsPi != NULL ); - Gia_ManLevelNum( pGia ); - Gia_ManForEachAnd( pGia, pObj, iObj ) - //if ( iObj == 6 ) - nCount += Gia_ObjSimRsb( p, iObj, nCands, fVerbose, &nBufs, &nInvs ); - printf( "Resubstitution is possible for %d nodes (%.2f %% out of %d) (Bufs = %d Invs = %d)\n", - nCount, 100.0*nCount/Gia_ManAndNum(pGia), Gia_ManAndNum(pGia), nBufs, nInvs ); - Gia_SimRsbFree( p ); - return nCount; -} - //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/giaSim4.c b/src/aig/gia/giaSim4.c index 610bb098..6ce89cf0 100644 --- a/src/aig/gia/giaSim4.c +++ b/src/aig/gia/giaSim4.c @@ -41,7 +41,7 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fVerbose ) +int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fVerbose ) { return 0; } diff --git a/src/aig/gia/giaSim5.c b/src/aig/gia/giaSim5.c new file mode 100644 index 00000000..ab33c218 --- /dev/null +++ b/src/aig/gia/giaSim5.c @@ -0,0 +1,56 @@ +/**CFile**************************************************************** + + FileName [giaSim5.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Simulation engine.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSim5.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "base/main/main.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +void Sim_Init( Abc_Frame_t * pAbc ) {} +void Sim_End( Abc_Frame_t * pAbc ) {} +void Gia_DatFree( Gia_Dat_t * p ) {} + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaSimBase.c b/src/aig/gia/giaSimBase.c new file mode 100644 index 00000000..c53c1db8 --- /dev/null +++ b/src/aig/gia/giaSimBase.c @@ -0,0 +1,2038 @@ +/**CFile**************************************************************** + + FileName [giaSim.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Scalable AIG package.] + + Synopsis [Fast sequential simulator.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: giaSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "gia.h" +#include "misc/util/utilTruth.h" +#include "misc/extra/extra.h" + +ABC_NAMESPACE_IMPL_START + + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + + +typedef struct Gia_SimRsbMan_t_ Gia_SimRsbMan_t; +struct Gia_SimRsbMan_t_ +{ + Gia_Man_t * pGia; + Vec_Int_t * vTfo; + Vec_Int_t * vCands; + Vec_Int_t * vFanins; + Vec_Int_t * vFanins2; + Vec_Wrd_t * vSimsObj; + Vec_Wrd_t * vSimsObj2; + int nWords; + word * pFunc[3]; +}; + + +typedef struct Gia_SimAbsMan_t_ Gia_SimAbsMan_t; +struct Gia_SimAbsMan_t_ +{ + // problem formulation + Gia_Man_t * pGia; // AIG manager + word * pSet[2]; // offset/onset truth tables + int nCands; // candidate count + int nWords; // word count + Vec_Wrd_t * vSims; // candidate simulation info + Vec_Int_t * vResub; // the result + int fVerbose; // verbose + // intermediate result + Vec_Int_t * vValues; // function values in each pattern + Vec_Int_t * vPatPairs; // used minterms + int nWordsTable; // words of table data + word * pTableTemp; // temporary table pattern + Vec_Wrd_t * vCoverTable; // columns = minterms; rows = classes + Vec_Int_t * vTtMints; // truth table minterms +}; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimPatAssignInputs( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsIn ) +{ + int i, Id; + assert( Vec_WrdSize(vSims) == nWords * Gia_ManObjNum(p) ); + assert( Vec_WrdSize(vSimsIn) == nWords * Gia_ManCiNum(p) ); + Gia_ManForEachCiId( p, Id, i ) + memcpy( Vec_WrdEntryP(vSims, Id*nWords), Vec_WrdEntryP(vSimsIn, i*nWords), sizeof(word)*nWords ); +} +static inline void Gia_ManSimPatSimAnd( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims ) +{ + word pComps[2] = { 0, ~(word)0 }; + word Diff0 = pComps[Gia_ObjFaninC0(pObj)]; + word Diff1 = pComps[Gia_ObjFaninC1(pObj)]; + word * pSims = Vec_WrdArray(vSims); + word * pSims0 = pSims + nWords*Gia_ObjFaninId0(pObj, i); + word * pSims1 = pSims + nWords*Gia_ObjFaninId1(pObj, i); + word * pSims2 = pSims + nWords*i; int w; + if ( Gia_ObjIsXor(pObj) ) + for ( w = 0; w < nWords; w++ ) + pSims2[w] = (pSims0[w] ^ Diff0) ^ (pSims1[w] ^ Diff1); + else + for ( w = 0; w < nWords; w++ ) + pSims2[w] = (pSims0[w] ^ Diff0) & (pSims1[w] ^ Diff1); +} +static inline void Gia_ManSimPatSimPo( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims ) +{ + word pComps[2] = { 0, ~(word)0 }; + word Diff0 = pComps[Gia_ObjFaninC0(pObj)]; + word * pSims = Vec_WrdArray(vSims); + word * pSims0 = pSims + nWords*Gia_ObjFaninId0(pObj, i); + word * pSims2 = pSims + nWords*i; int w; + for ( w = 0; w < nWords; w++ ) + pSims2[w] = (pSims0[w] ^ Diff0); +} +Vec_Wrd_t * Gia_ManSimPatSim( Gia_Man_t * pGia ) +{ + Gia_Obj_t * pObj; + int i, nWords = Vec_WrdSize(pGia->vSimsPi) / Gia_ManCiNum(pGia); + Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords ); + assert( Vec_WrdSize(pGia->vSimsPi) % Gia_ManCiNum(pGia) == 0 ); + Gia_ManSimPatAssignInputs( pGia, nWords, vSims, pGia->vSimsPi ); + Gia_ManForEachAnd( pGia, pObj, i ) + Gia_ManSimPatSimAnd( pGia, i, pObj, nWords, vSims ); + Gia_ManForEachCo( pGia, pObj, i ) + Gia_ManSimPatSimPo( pGia, Gia_ObjId(pGia, pObj), pObj, nWords, vSims ); + return vSims; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimPatValuesDerive( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vValues ) +{ + int i, Id; + assert( Vec_WrdSize(vSims) == nWords * Gia_ManObjNum(p) ); + assert( Vec_WrdSize(vValues) == nWords * Gia_ManCoNum(p) ); + Gia_ManForEachCoId( p, Id, i ) + memcpy( Vec_WrdEntryP(vValues, nWords * i), Vec_WrdEntryP(vSims, nWords * Id), sizeof(word)* nWords ); +} +Vec_Wrd_t * Gia_ManSimPatValues( Gia_Man_t * p ) +{ + int i, Id, nWords = Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p); + Vec_Wrd_t * vSims = Gia_ManSimPatSim( p ); + Vec_Wrd_t * vValues = Vec_WrdStart( Gia_ManCoNum(p) * nWords ); + assert( Vec_WrdSize(p->vSimsPi) == nWords * Gia_ManCiNum(p) ); + assert( Vec_WrdSize(vValues) == nWords * Gia_ManCoNum(p) ); + assert( Vec_WrdSize(vSims) == nWords * Gia_ManObjNum(p) ); + Gia_ManForEachCoId( p, Id, i ) + memcpy( Vec_WrdEntryP(vValues, nWords * i), Vec_WrdEntryP(vSims, nWords * Id), sizeof(word)* nWords ); + Vec_WrdFree( vSims ); + return vValues; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Wrd_t * Gia_ManSimCombine( int nInputs, Vec_Wrd_t * vBase, Vec_Wrd_t * vAddOn, int nWordsUse ) +{ + int nWordsBase = Vec_WrdSize(vBase) / nInputs; + int nWordsAddOn = Vec_WrdSize(vAddOn) / nInputs; int i, w; + Vec_Wrd_t * vSimsIn = Vec_WrdAlloc( nInputs * (nWordsBase + nWordsUse) ); + assert( Vec_WrdSize(vBase) % nInputs == 0 ); + assert( Vec_WrdSize(vAddOn) % nInputs == 0 ); + assert( nWordsUse <= nWordsAddOn ); + for ( i = 0; i < nInputs; i++ ) + { + word * pSimsB = nWordsBase ? Vec_WrdEntryP( vBase, i * nWordsBase ) : NULL; + word * pSimsA = nWordsAddOn ? Vec_WrdEntryP( vAddOn, i * nWordsAddOn ) : NULL; + for ( w = 0; w < nWordsBase; w++ ) + Vec_WrdPush( vSimsIn, pSimsB[w] ); + for ( w = 0; w < nWordsUse; w++ ) + Vec_WrdPush( vSimsIn, pSimsA[w] ); + } + assert( Vec_WrdSize(vSimsIn) == Vec_WrdCap(vSimsIn) || Vec_WrdSize(vSimsIn) < 16 ); + return vSimsIn; +} +int Gia_ManSimBitPackOne( int nWords, Vec_Wrd_t * vSimsIn, Vec_Wrd_t * vSimsCare, int iPat, int * pLits, int nLits ) +{ + word * pSimsI, * pSimsC; int i, k; + for ( i = 0; i < iPat; i++ ) + { + for ( k = 0; k < nLits; k++ ) + { + int iVar = Abc_Lit2Var( pLits[k] ); + pSimsI = Vec_WrdEntryP( vSimsIn, nWords * iVar ); + pSimsC = Vec_WrdEntryP( vSimsCare, nWords * iVar ); + if ( Abc_TtGetBit(pSimsC, i) && (Abc_TtGetBit(pSimsI, i) == Abc_LitIsCompl(pLits[k])) ) + break; + } + if ( k == nLits ) + break; + } + for ( k = 0; k < nLits; k++ ) + { + int iVar = Abc_Lit2Var( pLits[k] ); + pSimsI = Vec_WrdEntryP( vSimsIn, nWords * iVar ); + pSimsC = Vec_WrdEntryP( vSimsCare, nWords * iVar ); + if ( !Abc_TtGetBit(pSimsC, i) && Abc_TtGetBit(pSimsI, i) == Abc_LitIsCompl(pLits[k]) ) + Abc_TtXorBit( pSimsI, i ); + Abc_TtSetBit( pSimsC, i ); + assert( Abc_TtGetBit(pSimsC, i) && (Abc_TtGetBit(pSimsI, i) != Abc_LitIsCompl(pLits[k])) ); + } + return (int)(i == iPat); +} +Vec_Wrd_t * Gia_ManSimBitPacking( Gia_Man_t * p, Vec_Int_t * vCexStore, int nCexes, int nUnDecs ) +{ + int c, iCur = 0, iPat = 0; + int nWordsMax = Abc_Bit6WordNum( nCexes ); + Vec_Wrd_t * vSimsIn = Vec_WrdStartRandom( Gia_ManCiNum(p) * nWordsMax ); + Vec_Wrd_t * vSimsCare = Vec_WrdStart( Gia_ManCiNum(p) * nWordsMax ); + Vec_Wrd_t * vSimsRes = NULL; + for ( c = 0; c < nCexes + nUnDecs; c++ ) + { + int Out = Vec_IntEntry( vCexStore, iCur++ ); + int Size = Vec_IntEntry( vCexStore, iCur++ ); + if ( Size == -1 ) + continue; + iPat += Gia_ManSimBitPackOne( nWordsMax, vSimsIn, vSimsCare, iPat, Vec_IntEntryP(vCexStore, iCur), Size ); + iCur += Size; + assert( iPat <= nCexes + nUnDecs ); + Out = 0; + } + assert( iCur == Vec_IntSize(vCexStore) ); + vSimsRes = Gia_ManSimCombine( Gia_ManCiNum(p), p->vSimsPi, vSimsIn, Abc_Bit6WordNum(iPat+1) ); + printf( "Compressed %d CEXes into %d patterns and added %d words to available %d words.\n", + nCexes, iPat, Abc_Bit6WordNum(iPat+1), Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p) ); + Vec_WrdFree( vSimsIn ); + Vec_WrdFree( vSimsCare ); + return vSimsRes; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ManSimPatHashPatterns( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, int * pnC0, int * pnC1 ) +{ + Gia_Obj_t * pObj; + int i, nUnique; + Vec_Mem_t * vStore; + vStore = Vec_MemAlloc( nWords, 12 ); // 2^12 N-word entries per page + Vec_MemHashAlloc( vStore, 1 << 12 ); + Gia_ManForEachCand( p, pObj, i ) + { + word * pSim = Vec_WrdEntryP(vSims, i*nWords); + if ( pnC0 && Abc_TtIsConst0(pSim, nWords) ) + (*pnC0)++; + if ( pnC1 && Abc_TtIsConst1(pSim, nWords) ) + (*pnC1)++; + Vec_MemHashInsert( vStore, pSim ); + } + nUnique = Vec_MemEntryNum( vStore ); + Vec_MemHashFree( vStore ); + Vec_MemFree( vStore ); + return nUnique; +} +Gia_Man_t * Gia_ManSimPatGenMiter( Gia_Man_t * p, Vec_Wrd_t * vSims ) +{ + Gia_Man_t * pNew; + Gia_Obj_t * pObj; + int i, nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(p); + pNew = Gia_ManStart( Gia_ManObjNum(p) + Gia_ManCoNum(p) ); + Gia_ManHashStart( pNew ); + Gia_ManConst0(p)->Value = 0; + Gia_ManForEachCi( p, pObj, i ) + pObj->Value = Gia_ManAppendCi( pNew ); + Gia_ManForEachAnd( p, pObj, i ) + pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); + Gia_ManForEachAnd( p, pObj, i ) + { + word * pSim = Vec_WrdEntryP(vSims, i*nWords); + if ( Abc_TtIsConst0(pSim, nWords) ) + Gia_ManAppendCo( pNew, Abc_LitNotCond(pObj->Value, 0) ); + if ( Abc_TtIsConst1(pSim, nWords) ) + Gia_ManAppendCo( pNew, Abc_LitNotCond(pObj->Value, 1) ); + } + Gia_ManHashStop( pNew ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimPatWriteOne( FILE * pFile, word * pSim, int nWords ) +{ + int k, Digit, nDigits = nWords*16; + for ( k = 0; k < nDigits; k++ ) + { + Digit = (int)((pSim[k/16] >> ((k%16) * 4)) & 15); + if ( Digit < 10 ) + fprintf( pFile, "%d", Digit ); + else + fprintf( pFile, "%c", 'A' + Digit-10 ); + } + fprintf( pFile, "\n" ); +} +void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords ) +{ + int i, nNodes = Vec_WrdSize(vSimsIn) / nWords; + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + return; + } + assert( Vec_WrdSize(vSimsIn) % nWords == 0 ); + for ( i = 0; i < nNodes; i++ ) + Gia_ManSimPatWriteOne( pFile, Vec_WrdEntryP(vSimsIn, i*nWords), nWords ); + fclose( pFile ); + printf( "Written %d words of simulation data into file \"%s\".\n", nWords, pFileName ); +} +int Gia_ManSimPatReadOne( char c ) +{ + int Digit = 0; + if ( c >= '0' && c <= '9' ) + Digit = c - '0'; + else if ( c >= 'A' && c <= 'F' ) + Digit = c - 'A' + 10; + else if ( c >= 'a' && c <= 'f' ) + Digit = c - 'a' + 10; + else assert( 0 ); + assert( Digit >= 0 && Digit < 16 ); + return Digit; +} +Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName ) +{ + Vec_Wrd_t * vSimsIn = NULL; + int c, nWords = -1, nChars = 0; word Num = 0; + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return NULL; + } + vSimsIn = Vec_WrdAlloc( 1000 ); + while ( (c = fgetc(pFile)) != EOF ) + { + if ( c == '\n' && nWords == -1 ) + nWords = Vec_WrdSize(vSimsIn); + if ( c == '\n' || c == '\r' || c == '\t' || c == ' ' ) + continue; + Num |= (word)Gia_ManSimPatReadOne((char)c) << (nChars * 4); + if ( ++nChars < 16 ) + continue; + Vec_WrdPush( vSimsIn, Num ); + nChars = 0; + Num = 0; + } + assert( Vec_WrdSize(vSimsIn) % nWords == 0 ); + fclose( pFile ); + printf( "Read %d words of simulation data.\n", nWords ); + return vSimsIn; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimProfile( Gia_Man_t * pGia ) +{ + Vec_Wrd_t * vSims = Gia_ManSimPatSim( pGia ); + int nWords = Vec_WrdSize(vSims) / Gia_ManObjNum(pGia); + int nC0s = 0, nC1s = 0, nUnique = Gia_ManSimPatHashPatterns( pGia, nWords, vSims, &nC0s, &nC1s ); + printf( "Simulating %d patterns leads to %d unique objects (%.2f %% out of %d), Const0 = %d. Const1 = %d.\n", + 64*nWords, nUnique, 100.0*nUnique/Gia_ManCandNum(pGia), Gia_ManCandNum(pGia), nC0s, nC1s ); + Vec_WrdFree( vSims ); +} +void Gia_ManPatSatImprove( Gia_Man_t * p, int nWords0, int fVerbose ) +{ + extern Vec_Int_t * Cbs2_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose ); + int i, Status, Counts[3] = {0}; + Gia_Man_t * pGia; + Vec_Wrd_t * vSimsIn = NULL; + Vec_Str_t * vStatus = NULL; + Vec_Int_t * vCexStore = NULL; + Vec_Wrd_t * vSims = Gia_ManSimPatSim( p ); + //Gia_ManSimProfile( p ); + pGia = Gia_ManSimPatGenMiter( p, vSims ); + vCexStore = Cbs2_ManSolveMiterNc( pGia, 1000, &vStatus, 0 ); + Gia_ManStop( pGia ); + Vec_StrForEachEntry( vStatus, Status, i ) + { + assert( Status >= -1 && Status <= 1 ); + Counts[Status+1]++; + } + if ( fVerbose ) + printf( "Total = %d : SAT = %d. UNSAT = %d. UNDEC = %d.\n", Counts[1]+Counts[2]+Counts[0], Counts[1], Counts[2], Counts[0] ); + if ( Counts[1] == 0 ) + printf( "There are no counter-examples. No need for more simulation.\n" ); + else + { + vSimsIn = Gia_ManSimBitPacking( p, vCexStore, Counts[1], Counts[0] ); + Vec_WrdFreeP( &p->vSimsPi ); + p->vSimsPi = vSimsIn; + //Gia_ManSimProfile( p ); + } + Vec_StrFree( vStatus ); + Vec_IntFree( vCexStore ); + Vec_WrdFree( vSims ); +} + + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_SimRsbMan_t * Gia_SimRsbAlloc( Gia_Man_t * pGia ) +{ + Gia_SimRsbMan_t * p = ABC_CALLOC( Gia_SimRsbMan_t, 1 ); + p->pGia = pGia; + p->nWords = Vec_WrdSize(pGia->vSimsPi) / Gia_ManCiNum(pGia); assert( Vec_WrdSize(pGia->vSimsPi) % Gia_ManCiNum(pGia) == 0 ); + p->pFunc[0] = ABC_CALLOC( word, p->nWords ); + p->pFunc[1] = ABC_CALLOC( word, p->nWords ); + p->pFunc[2] = ABC_CALLOC( word, p->nWords ); + p->vTfo = Vec_IntAlloc( 1000 ); + p->vCands = Vec_IntAlloc( 1000 ); + p->vFanins = Vec_IntAlloc( 10 ); + p->vFanins2 = Vec_IntAlloc( 10 ); + p->vSimsObj = Gia_ManSimPatSim( pGia ); + p->vSimsObj2 = Vec_WrdStart( Vec_WrdSize(p->vSimsObj) ); + assert( p->nWords == Vec_WrdSize(p->vSimsObj) / Gia_ManObjNum(pGia) ); + Gia_ManStaticFanoutStart( pGia ); + return p; +} +void Gia_SimRsbFree( Gia_SimRsbMan_t * p ) +{ + Gia_ManStaticFanoutStop( p->pGia ); + Vec_IntFree( p->vTfo ); + Vec_IntFree( p->vCands ); + Vec_IntFree( p->vFanins ); + Vec_IntFree( p->vFanins2 ); + Vec_WrdFree( p->vSimsObj ); + Vec_WrdFree( p->vSimsObj2 ); + ABC_FREE( p->pFunc[0] ); + ABC_FREE( p->pFunc[1] ); + ABC_FREE( p->pFunc[2] ); + ABC_FREE( p ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_SimRsbTfo_rec( Gia_Man_t * p, int iObj, int iFanout, Vec_Int_t * vTfo ) +{ + int i, iFan; + if ( Gia_ObjIsTravIdCurrentId(p, iObj) ) + return; + Gia_ObjSetTravIdCurrentId(p, iObj); + Gia_ObjForEachFanoutStaticId( p, iObj, iFan, i ) + if ( iFanout == -1 || iFan == iFanout ) + Gia_SimRsbTfo_rec( p, iFan, -1, vTfo ); + Vec_IntPush( vTfo, iObj ); +} +Vec_Int_t * Gia_SimRsbTfo( Gia_SimRsbMan_t * p, int iObj, int iFanout ) +{ + assert( iObj > 0 ); + Vec_IntClear( p->vTfo ); + Gia_ManIncrementTravId( p->pGia ); + Gia_SimRsbTfo_rec( p->pGia, iObj, iFanout, p->vTfo ); + assert( Vec_IntEntryLast(p->vTfo) == iObj ); + Vec_IntPop( p->vTfo ); + Vec_IntReverseOrder( p->vTfo ); + Vec_IntSort( p->vTfo, 0 ); + return p->vTfo; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +word * Gia_SimRsbFunc( Gia_SimRsbMan_t * p, int iObj, Vec_Int_t * vFanins, int fOnSet ) +{ + int nTruthWords = Abc_Truth6WordNum( Vec_IntSize(vFanins) ); + word * pTruth = ABC_CALLOC( word, nTruthWords ); + word * pFunc = Vec_WrdEntryP( p->vSimsObj, p->nWords*iObj ); + word * pFanins[16] = {NULL}; int s, b, iMint, i, iFanin; + assert( Vec_IntSize(vFanins) <= 16 ); + Vec_IntForEachEntry( vFanins, iFanin, i ) + pFanins[i] = Vec_WrdEntryP( p->vSimsObj, p->nWords*iFanin ); + for ( s = 0; s < 64*p->nWords; s++ ) + { + if ( !Abc_TtGetBit(p->pFunc[2], s) || Abc_TtGetBit(pFunc, s) != fOnSet ) + continue; + iMint = 0; + for ( b = 0; b < Vec_IntSize(vFanins); b++ ) + if ( Abc_TtGetBit(pFanins[b], s) ) + iMint |= 1 << b; + Abc_TtSetBit( pTruth, iMint ); + } + return pTruth; +} +int Gia_SimRsbResubVerify( Gia_SimRsbMan_t * p, int iObj, Vec_Int_t * vFanins ) +{ + word * pTruth0 = Gia_SimRsbFunc( p, iObj, p->vFanins, 0 ); + word * pTruth1 = Gia_SimRsbFunc( p, iObj, p->vFanins, 1 ); + int Res = !Abc_TtIntersect( pTruth0, pTruth1, p->nWords, 0 ); + ABC_FREE( pTruth0 ); + ABC_FREE( pTruth1 ); + return Res; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline void Gia_SimRsbSimAndCareSet( Gia_Man_t * p, int i, Gia_Obj_t * pObj, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSims2 ) +{ + word pComps[2] = { 0, ~(word)0 }; + word Diff0 = pComps[Gia_ObjFaninC0(pObj)]; + word Diff1 = pComps[Gia_ObjFaninC1(pObj)]; + Vec_Wrd_t * vSims0 = Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) ? vSims2 : vSims; + Vec_Wrd_t * vSims1 = Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) ? vSims2 : vSims; + word * pSims0 = Vec_WrdEntryP( vSims0, nWords*Gia_ObjFaninId0(pObj, i) ); + word * pSims1 = Vec_WrdEntryP( vSims1, nWords*Gia_ObjFaninId1(pObj, i) ); + word * pSims2 = Vec_WrdEntryP( vSims2, nWords*i ); int w; + if ( Gia_ObjIsXor(pObj) ) + for ( w = 0; w < nWords; w++ ) + pSims2[w] = (pSims0[w] ^ Diff0) ^ (pSims1[w] ^ Diff1); + else + for ( w = 0; w < nWords; w++ ) + pSims2[w] = (pSims0[w] ^ Diff0) & (pSims1[w] ^ Diff1); +} +word * Gia_SimRsbCareSet( Gia_SimRsbMan_t * p, int iObj, Vec_Int_t * vTfo ) +{ + word * pSims = Vec_WrdEntryP( p->vSimsObj, p->nWords*iObj ); + word * pSims2 = Vec_WrdEntryP( p->vSimsObj2, p->nWords*iObj ); int iNode, i; + Abc_TtCopy( pSims2, pSims, p->nWords, 1 ); + Abc_TtClear( p->pFunc[2], p->nWords ); + Vec_IntForEachEntry( vTfo, iNode, i ) + { + Gia_Obj_t * pNode = Gia_ManObj(p->pGia, iNode); + if ( Gia_ObjIsAnd(pNode) ) + Gia_SimRsbSimAndCareSet( p->pGia, iNode, pNode, p->nWords, p->vSimsObj, p->vSimsObj2 ); + else if ( Gia_ObjIsCo(pNode) ) + { + word * pSimsA = Vec_WrdEntryP( p->vSimsObj, p->nWords*Gia_ObjFaninId0p(p->pGia, pNode) ); + word * pSimsB = Vec_WrdEntryP( p->vSimsObj2, p->nWords*Gia_ObjFaninId0p(p->pGia, pNode) ); + Abc_TtOrXor( p->pFunc[2], pSimsA, pSimsB, p->nWords ); + } + else assert( 0 ); + } + return p->pFunc[2]; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ObjSimCollect( Gia_SimRsbMan_t * p ) +{ + int i, k, iTemp, iFanout; + Vec_IntClear( p->vFanins2 ); + assert( Vec_IntSize(p->vFanins) > 0 ); + Vec_IntForEachEntry( p->vFanins, iTemp, i ) + { + Gia_Obj_t * pObj = Gia_ManObj( p->pGia, iTemp ); + if ( Gia_ObjIsAnd(pObj) && !Gia_ObjIsTravIdCurrentId( p->pGia, Gia_ObjFaninId0(pObj, iTemp) ) ) + Vec_IntPush( p->vFanins2, Gia_ObjFaninId0(pObj, iTemp) ); + if ( Gia_ObjIsAnd(pObj) && !Gia_ObjIsTravIdCurrentId( p->pGia, Gia_ObjFaninId1(pObj, iTemp) ) ) + Vec_IntPush( p->vFanins2, Gia_ObjFaninId1(pObj, iTemp) ); + Gia_ObjForEachFanoutStaticId( p->pGia, iTemp, iFanout, k ) + if ( Gia_ObjIsAnd(Gia_ManObj(p->pGia, iFanout)) && !Gia_ObjIsTravIdCurrentId( p->pGia, iFanout ) ) + Vec_IntPush( p->vFanins2, iFanout ); + } +} +Vec_Int_t * Gia_ObjSimCands( Gia_SimRsbMan_t * p, int iObj, int nCands ) +{ + assert( iObj > 0 ); + assert( Gia_ObjIsAnd(Gia_ManObj(p->pGia, iObj)) ); + Vec_IntClear( p->vCands ); + Vec_IntFill( p->vFanins, 1, iObj ); + while ( Vec_IntSize(p->vFanins) > 0 && Vec_IntSize(p->vCands) < nCands ) + { + int i, iTemp; + Vec_IntForEachEntry( p->vFanins, iTemp, i ) + Gia_ObjSetTravIdCurrentId( p->pGia, iTemp ); + Gia_ObjSimCollect( p ); // p->vFanins -> p->vFanins2 + Vec_IntAppend( p->vCands, p->vFanins2 ); + ABC_SWAP( Vec_Int_t *, p->vFanins, p->vFanins2 ); + } + assert( Vec_IntSize(p->vFanins) == 0 || Vec_IntSize(p->vCands) >= nCands ); + if ( Vec_IntSize(p->vCands) > nCands ) + Vec_IntShrink( p->vCands, nCands ); + return p->vCands; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_ObjSimRsb( Gia_SimRsbMan_t * p, int iObj, int nCands, int fVerbose, int * pnBufs, int * pnInvs ) +{ + int i, iCand, RetValue = 0; + Vec_Int_t * vTfo = Gia_SimRsbTfo( p, iObj, -1 ); + word * pCareSet = Gia_SimRsbCareSet( p, iObj, vTfo ); + word * pFunc = Vec_WrdEntryP( p->vSimsObj, p->nWords*iObj ); + Vec_Int_t * vCands = Gia_ObjSimCands( p, iObj, nCands ); + Abc_TtAndSharp( p->pFunc[0], pCareSet, pFunc, p->nWords, 1 ); + Abc_TtAndSharp( p->pFunc[1], pCareSet, pFunc, p->nWords, 0 ); + +/* +printf( "Considering node %d with %d candidates:\n", iObj, Vec_IntSize(vCands) ); +Vec_IntPrint( vTfo ); +Vec_IntPrint( vCands ); +Extra_PrintBinary( stdout, (unsigned *)pCareSet, 64 ); printf( "\n" ); +Extra_PrintBinary( stdout, (unsigned *)pFunc, 64 ); printf( "\n" ); +Extra_PrintBinary( stdout, (unsigned *)p->pFunc[0], 64 ); printf( "\n" ); +Extra_PrintBinary( stdout, (unsigned *)p->pFunc[1], 64 ); printf( "\n" ); +*/ + Vec_IntForEachEntry( vCands, iCand, i ) + { + word * pDiv = Vec_WrdEntryP( p->vSimsObj, p->nWords*iCand ); + if ( !Abc_TtIntersect(pDiv, p->pFunc[0], p->nWords, 0) && + !Abc_TtIntersect(pDiv, p->pFunc[1], p->nWords, 1) ) + { (*pnBufs)++; if ( fVerbose ) printf( "Level %3d : %d = buf(%d)\n", Gia_ObjLevelId(p->pGia, iObj), iObj, iCand ); RetValue = 1; } + if ( !Abc_TtIntersect(pDiv, p->pFunc[0], p->nWords, 1) && + !Abc_TtIntersect(pDiv, p->pFunc[1], p->nWords, 0) ) + { (*pnInvs)++; if ( fVerbose ) printf( "Level %3d : %d = inv(%d)\n", Gia_ObjLevelId(p->pGia, iObj), iObj, iCand ); RetValue = 1; } + } + return RetValue; +} + +int Gia_ManSimRsb( Gia_Man_t * pGia, int nCands, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Gia_Obj_t * pObj; int iObj, nCount = 0, nBufs = 0, nInvs = 0; + Gia_SimRsbMan_t * p = Gia_SimRsbAlloc( pGia ); + assert( pGia->vSimsPi != NULL ); + Gia_ManLevelNum( pGia ); + Gia_ManForEachAnd( pGia, pObj, iObj ) + //if ( iObj == 6 ) + nCount += Gia_ObjSimRsb( p, iObj, nCands, fVerbose, &nBufs, &nInvs ); + printf( "Can resubstitute %d nodes (%.2f %% out of %d) (Bufs = %d Invs = %d) ", + nCount, 100.0*nCount/Gia_ManAndNum(pGia), Gia_ManAndNum(pGia), nBufs, nInvs ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + Gia_SimRsbFree( p ); + return nCount; +} + + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimRelAssignInputs( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, int nWordsIn, Vec_Wrd_t * vSimsIn ) +{ + int i, m, Id, nMints = nWords / nWordsIn; + assert( Vec_WrdSize(vSims) == nWords * Gia_ManObjNum(p) ); + assert( Vec_WrdSize(vSimsIn) == nWordsIn * Gia_ManCiNum(p) ); + Gia_ManForEachCiId( p, Id, i ) + for ( m = 0; m < nMints; m++ ) + memcpy( Vec_WrdEntryP(vSims, Id * nWords + nWordsIn * m), + Vec_WrdEntryP(vSimsIn, i * nWordsIn), sizeof(word) * nWordsIn ); +} +int Gia_ManSimRelCompare( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, int nWordsOut, Vec_Wrd_t * vSimsOut, int iPat, int iMint ) +{ + int i, Id; + Gia_ManForEachCoId( p, Id, i ) + { + word * pSim = Vec_WrdEntryP( vSims, nWords * Id + iMint * nWordsOut ); + word * pSimOut = Vec_WrdEntryP( vSimsOut, nWordsOut * i ); +/* + int k; + for ( k = 0; k < 64*nWordsOut; k++ ) + printf( "%d", Abc_TtGetBit( pSim, k ) ); + printf( "\n" ); + for ( k = 0; k < 64*nWordsOut; k++ ) + printf( "%d", Abc_TtGetBit( pSimOut, k ) ); + printf( "\n\n" ); +*/ + if ( Abc_TtGetBit(pSim, iPat) != Abc_TtGetBit(pSimOut, iPat) ) + return 0; + } + return 1; +} +int Gia_ManSimRelCollectOutputs( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, int nWordsOut, Vec_Wrd_t * vSimsOut, Vec_Wrd_t * vRel ) +{ + int i, m, nMints = nWords / nWordsOut, Count = 0; + assert( Vec_WrdSize(vSims) == nWords * Gia_ManObjNum(p) ); + assert( Vec_WrdSize(vSimsOut) == nWordsOut * Gia_ManCoNum(p) ); + assert( Vec_WrdSize(vRel) == nWordsOut * nMints ); + for ( i = 0; i < 64 * nWordsOut; i++ ) + { + int CountMints = 0; + for ( m = 0; m < nMints; m++ ) + if ( Gia_ManSimRelCompare(p, nWords, vSims, nWordsOut, vSimsOut, i, m) ) + Abc_TtSetBit( Vec_WrdArray(vRel), i*nMints+m ), CountMints++; + Count += CountMints == 0; + } + if ( Count ) + printf( "The relation is not well-defined for %d (out of %d) patterns.\n", Count, 64 * nWordsOut ); + return Count; +} +Vec_Wrd_t * Gia_ManSimRel( Gia_Man_t * p, Vec_Int_t * vObjs, Vec_Wrd_t * vVals ) +{ + int nWords = Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p); + int nMints = 1 << Vec_IntSize(vObjs), i, m, iObj; + Gia_Obj_t * pObj; + Vec_Wrd_t * vRel = Vec_WrdStart( nWords * nMints ); + Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords * nMints ); + Gia_ManSimRelAssignInputs( p, nWords * nMints, vSims, nWords, p->vSimsPi ); + Vec_IntForEachEntry( vObjs, iObj, i ) + for ( m = 0; m < nMints; m++ ) + if ( (m >> i) & 1 ) + memset( Vec_WrdEntryP(vSims, iObj*nMints*nWords + nWords*m), 0xFF, sizeof(word)*nWords ); + else + memset( Vec_WrdEntryP(vSims, iObj*nMints*nWords + nWords*m), 0x00, sizeof(word)*nWords ); + Gia_ManCleanPhase( p ); + Gia_ManForEachObjVec( vObjs, p, pObj, i ) + pObj->fPhase = 1; + Gia_ManForEachAnd( p, pObj, i ) + if ( !pObj->fPhase ) + Gia_ManSimPatSimAnd( p, i, pObj, nWords * nMints, vSims ); + Gia_ManForEachCo( p, pObj, i ) + if ( !pObj->fPhase ) + Gia_ManSimPatSimPo( p, Gia_ObjId(p, pObj), pObj, nWords * nMints, vSims ); + Gia_ManForEachObjVec( vObjs, p, pObj, i ) + pObj->fPhase = 0; + if ( Gia_ManSimRelCollectOutputs( p, nWords * nMints, vSims, nWords, vVals, vRel ) ) + Vec_WrdFreeP( &vRel ); + Vec_WrdFree( vSims ); + return vRel; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimRelCheckFuncs( Gia_Man_t * p, Vec_Wrd_t * vRel, int nOuts, Vec_Wrd_t * vFuncs ) +{ + int i, k, m, Values[32], nErrors = 0, nMints = 1 << nOuts, nWords = Vec_WrdSize(vRel) / nMints; + assert( Vec_WrdSize(vFuncs) == 2 * nOuts * nWords ); + assert( nOuts <= 32 ); + for ( i = 0; i < 64 * nWords; i++ ) + { + for ( k = 0; k < nOuts; k++ ) + { + int Value0 = Abc_TtGetBit( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), i ); + int Value1 = Abc_TtGetBit( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), i ); + if ( Value0 && !Value1 ) + Values[k] = 1; + else if ( !Value0 && Value1 ) + Values[k] = 2; + else if ( !Value0 && !Value1 ) + Values[k] = 3; + else assert( 0 ); + } + for ( m = 0; m < nMints; m++ ) + { + for ( k = 0; k < nOuts; k++ ) + if ( ((Values[k] >> ((m >> k) & 1)) & 1) == 0 ) + break; + if ( k < nOuts ) + continue; + if ( Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+m ) ) + continue; + if ( nErrors++ == 0 ) + printf( "For pattern %d, minterm %d produced by function is not in the relation.\n", i, m ); + } + } + if ( nErrors ) + printf( "Total number of similar errors = %d.\n", nErrors ); + else + printf( "The function agrees with the relation.\n" ); +} +Vec_Wrd_t * Gia_ManSimRelDeriveFuncs( Gia_Man_t * p, Vec_Wrd_t * vRel, int nOuts ) +{ + int i, k, m, Count = 0, nMints = 1 << nOuts, nWords = Vec_WrdSize(vRel) / nMints; + Vec_Wrd_t * vFuncs = Vec_WrdStart( 2 * nOuts * nWords ); + assert( Vec_WrdSize(vRel) % nMints == 0 ); + for ( i = 0; i < 64 * nWords; i++ ) + { + for ( m = 0; m < nMints; m++ ) + if ( Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+m ) ) + break; + Count += m == nMints; + for ( k = 0; k < nOuts; k++ ) + if ( (m >> k) & 1 ) + Abc_TtSetBit( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), i ); + else + Abc_TtSetBit( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), i ); + } + if ( Count ) + printf( "The relation is not well-defined for %d (out of %d) patterns.\n", Count, 64 * nWords ); + else + printf( "The relation was successfully determized without don't-cares for %d patterns.\n", 64 * nWords ); + Gia_ManSimRelCheckFuncs( p, vRel, nOuts, vFuncs ); + return vFuncs; +} +Vec_Wrd_t * Gia_ManSimRelDeriveFuncs2( Gia_Man_t * p, Vec_Wrd_t * vRel, int nOuts ) +{ + int i, k, m, nDCs[32] = {0}, Count = 0, nMints = 1 << nOuts, nWords = Vec_WrdSize(vRel) / nMints; + Vec_Wrd_t * vFuncs = Vec_WrdStart( 2 * nOuts * nWords ); + assert( Vec_WrdSize(vRel) % nMints == 0 ); + assert( nOuts <= 32 ); + for ( i = 0; i < 64 * nWords; i++ ) + { + for ( m = 0; m < nMints; m++ ) + if ( Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+m ) ) + break; + Count += m == nMints; + for ( k = 0; k < nOuts; k++ ) + { + if ( Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+(m^(1<<k)) ) ) + { + nDCs[k]++; + continue; + } + if ( (m >> k) & 1 ) + Abc_TtSetBit( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), i ); + else + Abc_TtSetBit( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), i ); + } + if ( 0 ) + { + for ( m = 0; m < nMints; m++ ) + printf( "%d", Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+m ) ); + printf( " " ); + for ( k = 0; k < nOuts; k++ ) + { + if ( Abc_TtGetBit( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), i ) ) + printf( "0" ); + else if ( Abc_TtGetBit( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), i ) ) + printf( "1" ); + else + printf( "-" ); + } + printf( "\n" ); + } + } + if ( Count ) + printf( "The relation is not well-defined for %d (out of %d) patterns.\n", Count, 64 * nWords ); + else + { + printf( "The relation was successfully determized with don't-cares for %d patterns.\n", 64 * nWords ); + for ( k = 0; k < nOuts; k++ ) + { + int nOffs = Abc_TtCountOnesVec( Vec_WrdEntryP(vFuncs, (2*k+0)*nWords), nWords ); + int nOns = Abc_TtCountOnesVec( Vec_WrdEntryP(vFuncs, (2*k+1)*nWords), nWords ); + printf( "%4d : Off = %6d On = %6d Dc = %6d (%6.2f %%)\n", k, nOffs, nOns, nDCs[k], 100.0*nDCs[k]/(64*nWords) ); + } + printf( "\n" ); + } + Gia_ManSimRelCheckFuncs( p, vRel, nOuts, vFuncs ); + return vFuncs; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_ManSimRelPrint( Gia_Man_t * p, Vec_Wrd_t * vRel, Vec_Int_t * vOutMints ) +{ + int nWords = Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p); + int nMints = Vec_WrdSize(vRel) / nWords; + int i, m, Count; +/* + for ( i = 0; i < 64 * nWords; i++ ) + { + int k; + for ( k = 0; k < Gia_ManCiNum(p); k++ ) + printf( "%d", Abc_TtGetBit( Vec_WrdEntryP(p->vSimsPi, k), i ) ); + printf( " " ); + Count = 0; + for ( m = 0; m < nMints; m++ ) + { + printf( "%d", Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+m ) ); + Count += Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+m ); + } + printf( " Count = %2d ", Count ); + if ( vOutMints ) + { + printf( " %3d ", Vec_IntEntry(vOutMints, i) ); + if ( Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+Vec_IntEntry(vOutMints, i) ) ) + printf( "yes" ); + else + printf( "no" ); + } + printf( "\n" ); + } +*/ +/* + for ( i = 0; i < 64 * nWords; i++ ) + { + Count = 0; + for ( m = 0; m < nMints; m++ ) + Count += Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+m ); + printf( "%d ", Count ); + } + printf( "\n" ); +*/ + for ( i = 0; i < 64 * nWords; i++ ) + { + Count = 0; + for ( m = 0; m < nMints; m++ ) + { + printf( "%d", Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+m ) ); + Count += Abc_TtGetBit( Vec_WrdArray(vRel), i*nMints+m ); + } + printf( " Count = %2d \n", Count ); + } +} +Vec_Int_t * Gia_ManSimPatStart( int nItems ) +{ + Vec_Int_t * vValues = Vec_IntAlloc( nItems ); + Vec_IntPush( vValues, 17 ); + Vec_IntPush( vValues, 39 ); + Vec_IntPush( vValues, 56 ); + Vec_IntPush( vValues, 221 ); + return vValues; +} +void Gia_ManSimRelTest( Gia_Man_t * p ) +{ + //int nWords = Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p); + Vec_Int_t * vObjs = Gia_ManSimPatStart( 4 ); // can be CI/AND/CO + Vec_Wrd_t * vVals = Gia_ManSimPatValues( p ); + Vec_Wrd_t * vRel = Gia_ManSimRel( p, vObjs, vVals ); + assert( p->vSimsPi != NULL ); + Gia_ManSimRelPrint( p, vRel, NULL ); + Vec_IntFree( vObjs ); + Vec_WrdFree( vVals ); + Vec_WrdFree( vRel ); +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_Sim5CollectValues( word * pOffSet, word * pOnSet, int nWords ) +{ + Vec_Int_t * vBits = Vec_IntAlloc( 64*nWords ); int i, Count[2] = {0}; + for ( i = 0; i < 64*nWords; i++ ) + if ( Abc_TtGetBit( pOffSet, i ) ) + Vec_IntPush( vBits, 0 ), Count[0]++; + else if ( Abc_TtGetBit( pOnSet, i ) ) + Vec_IntPush( vBits, 1 ), Count[1]++; + else + Vec_IntPush( vBits, -1 ); + //printf( "Offset = %d. Onset = %d. Dcset = %d.\n", Count[0], Count[1], 64*nWords - Count[0] - Count[1] ); + return vBits; +} +Gia_SimAbsMan_t * Gia_SimAbsAlloc( Gia_Man_t * pGia, word * pOffSet, word * pOnSet, Vec_Wrd_t * vSims, int nWords, Vec_Int_t * vResub, int fVerbose ) +{ + Gia_SimAbsMan_t * p = ABC_CALLOC( Gia_SimAbsMan_t, 1 ); + p->pGia = pGia; + p->pSet[0] = pOffSet; + p->pSet[1] = pOnSet; + p->nCands = Vec_WrdSize(vSims)/nWords; + p->nWords = nWords; + p->vSims = vSims; + p->vResub = vResub; + p->fVerbose = fVerbose; + p->vValues = Gia_Sim5CollectValues( pOffSet, pOnSet, nWords ); + p->vPatPairs = Vec_IntAlloc( 100 ); + p->vCoverTable = Vec_WrdAlloc( 10000 ); + p->vTtMints = Vec_IntAlloc( 100 ); + assert( Vec_WrdSize(vSims) % nWords == 0 ); + return p; +} +void Gia_SimAbsFree( Gia_SimAbsMan_t * p ) +{ + Vec_IntFree( p->vValues ); + Vec_IntFree( p->vPatPairs ); + Vec_WrdFree( p->vCoverTable ); + Vec_IntFree( p->vTtMints ); + ABC_FREE( p ); +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Gia_SimAbsCheckSolution( Gia_SimAbsMan_t * p ) +{ + int x, y, z, w, fFound = 0; + assert( Vec_WrdSize(p->vCoverTable) == p->nWordsTable * (p->nCands+1) ); + + Abc_TtClear( p->pTableTemp, p->nWordsTable ); + for ( x = 0; x < Vec_IntSize(p->vPatPairs)/2; x++ ) + Abc_TtXorBit( p->pTableTemp, x ); + + for ( x = 0; x < p->nCands; x++ ) + { + word * pSimTableX = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * x ); + for ( w = 0; w < p->nWordsTable; w++ ) + if ( p->pTableTemp[w] != pSimTableX[w] ) + break; + if ( w == p->nWordsTable ) + { + printf( "Found solution { %d }\n", x ); + fFound = 1; + } + } + if ( fFound ) + return; + + for ( x = 0; x < p->nCands; x++ ) + for ( y = 0; y < x; y++ ) + { + word * pSimTableX = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * x ); + word * pSimTableY = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * y ); + for ( w = 0; w < p->nWordsTable; w++ ) + if ( p->pTableTemp[w] != (pSimTableX[w] | pSimTableY[w]) ) + break; + if ( w == p->nWordsTable ) + { + printf( "Found solution { %d %d }\n", y, x ); + fFound = 1; + } + } + if ( fFound ) + return; + + for ( x = 0; x < p->nCands; x++ ) + for ( y = 0; y < x; y++ ) + for ( z = 0; z < y; z++ ) + { + word * pSimTableX = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * x ); + word * pSimTableY = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * y ); + word * pSimTableZ = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * z ); + for ( w = 0; w < p->nWordsTable; w++ ) + if ( p->pTableTemp[w] != (pSimTableX[w] | pSimTableY[w] | pSimTableZ[w]) ) + break; + if ( w == p->nWordsTable ) + printf( "Found solution { %d %d %d }\n", z, y, x ); + } +} + +void Gia_SimAbsSolve( Gia_SimAbsMan_t * p ) +{ + abctime clk = Abc_Clock(); + int i, k, iPat, iPat2; +/* + Vec_Int_t * vSimPats = Vec_IntDup( p->vPatPairs ); + Vec_IntUniqify( vSimPats ); + printf( "Selected %d pattern pairs contain %d unique patterns.\n", Vec_IntSize(p->vPatPairs)/2, Vec_IntSize(vSimPats) ); + Vec_IntFree( vSimPats ); +*/ + // set up the covering problem + p->nWordsTable = Abc_Bit6WordNum( Vec_IntSize(p->vPatPairs)/2 ); + Vec_WrdFill( p->vCoverTable, p->nWordsTable * (p->nCands + 1), 0 ); + p->pTableTemp = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * p->nCands ); + for ( i = 0; i < p->nCands; i++ ) + { + word * pSimCand = Vec_WrdEntryP( p->vSims, p->nWords * i ); + word * pSimTable = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * i ); + //printf( "%4d : ", i ); + //Extra_PrintBinary( stdout, (word *)pSimCand, p->nCands ); printf( "\n" ); + Vec_IntForEachEntryDouble( p->vPatPairs, iPat, iPat2, k ) + { + assert( Vec_IntEntry(p->vValues, iPat) == 0 ); + assert( Vec_IntEntry(p->vValues, iPat2) == 1 ); + if ( Abc_TtGetBit(pSimCand, iPat) != Abc_TtGetBit(pSimCand, iPat2) ) + Abc_TtXorBit(pSimTable, k/2); + } + assert( k == Vec_IntSize(p->vPatPairs) ); + } + + if ( 0 ) + { + printf( " " ); + for ( i = 0; i < p->nCands; i++ ) + printf( "%d", i % 10 ); + printf( "\n" ); + + Vec_IntForEachEntryDouble( p->vPatPairs, iPat, iPat2, i ) + { + printf( "%4d ", i/2 ); + printf( "%4d ", iPat ); + printf( "%4d ", iPat2 ); + for ( k = 0; k < p->nCands; k++ ) + { + word * pSimTable = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * k ); + printf( "%c", Abc_TtGetBit(pSimTable, i/2) ? '*' : ' ' ); + } + printf( "\n" ); + } + } + + //Gia_SimAbsCheckSolution(p); + + Vec_IntClear( p->vResub ); + Abc_TtClear( p->pTableTemp, p->nWordsTable ); + for ( i = 0; i < Vec_IntSize(p->vPatPairs)/2; i++ ) + Abc_TtXorBit( p->pTableTemp, i ); + + while ( !Abc_TtIsConst0(p->pTableTemp, p->nWordsTable) ) + { + word * pSimTable; + int iArgMax = -1, CostThis, CostMax = -1; + // compute the cost of each column + for ( i = 0; i < p->nCands; i++ ) + { + pSimTable = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * i ); + CostThis = Abc_TtCountOnesVecMask( pSimTable, p->pTableTemp, p->nWordsTable, 0 ); + if ( CostMax >= CostThis ) + continue; + CostMax = CostThis; + iArgMax = i; + } + // find the best column + Vec_IntPush( p->vResub, iArgMax ); + // delete values of this column + pSimTable = Vec_WrdEntryP( p->vCoverTable, p->nWordsTable * iArgMax ); + Abc_TtSharp( p->pTableTemp, p->pTableTemp, pSimTable, p->nWordsTable ); + } + if ( p->fVerbose ) + { + printf( "Solution %2d for covering problem [%5d x %5d]: ", Vec_IntSize(p->vResub), Vec_IntSize(p->vPatPairs)/2, p->nCands ); + Vec_IntForEachEntry( p->vResub, iPat, i ) + printf( "%6d ", iPat ); + for ( ; i < 12; i++ ) + printf( " " ); + printf( " " ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } +} +int Gia_SimAbsRefine( Gia_SimAbsMan_t * p ) +{ + int i, b, Value, iPat, iMint, iObj, Count = 0; + word ** pFanins = ABC_ALLOC( word *, Vec_IntSize(p->vResub) ); + assert( Vec_IntSize(p->vResub) > 0 ); + Vec_IntForEachEntry( p->vResub, iObj, b ) + pFanins[b] = Vec_WrdEntryP( p->vSims, p->nWords * iObj ); + Vec_IntFill( p->vTtMints, 1 << Vec_IntSize(p->vResub), -1 ); + Vec_IntForEachEntry( p->vValues, Value, i ) + { + if ( Value == -1 ) + continue; + iMint = 0; + for ( b = 0; b < Vec_IntSize(p->vResub); b++ ) + if ( Abc_TtGetBit(pFanins[b], i) ) + iMint |= 1 << b; + iPat = Vec_IntEntry( p->vTtMints, iMint ); + if ( iPat == -1 ) + { + Vec_IntWriteEntry( p->vTtMints, iMint, i ); + continue; + } + assert( Abc_TtGetBit(p->pSet[Value], i) ); + if ( Abc_TtGetBit(p->pSet[Value], iPat) ) + continue; + assert( Abc_TtGetBit(p->pSet[!Value], iPat) ); + Vec_IntPushTwo( p->vPatPairs, Value ? iPat : i, Value ? i : iPat ); + //printf( "iPat1 = %d iPat2 = %d Mint = %d\n", Value ? iPat : i, Value ? i : iPat, iMint ); + Count++; + if ( Count == 64 ) + { + ABC_FREE( pFanins ); + return 1; + } + } + //printf( "Refinement added %d minterm pairs.\n", Count ); + ABC_FREE( pFanins ); + return Count != 0; +} +Vec_Int_t * Gia_SimAbsFind( Vec_Int_t * vValues, int Value ) +{ + Vec_Int_t * vSubset = Vec_IntAlloc( 100 ); int i, Entry; + Vec_IntForEachEntry( vValues, Entry, i ) + if ( Entry == Value ) + Vec_IntPush( vSubset, i ); + return vSubset; +} +void Gia_SimAbsInit( Gia_SimAbsMan_t * p ) +{ + int n, nPairsInit = 64; + Vec_Int_t * vValue0 = Gia_SimAbsFind( p->vValues, 0 ); + Vec_Int_t * vValue1 = Gia_SimAbsFind( p->vValues, 1 ); + Vec_IntClear( p->vPatPairs ); + printf( "There are %d offset and %d onset minterms (%d pairs) and %d divisors.\n", + Vec_IntSize(vValue0), Vec_IntSize(vValue1), Vec_IntSize(vValue0)*Vec_IntSize(vValue1), p->nCands ); + Abc_Random( 1 ); + assert( Vec_IntSize(vValue0) > 0 ); + assert( Vec_IntSize(vValue1) > 0 ); + for ( n = 0; n < nPairsInit; n++ ) + Vec_IntPushTwo( p->vPatPairs, + Vec_IntEntry(vValue0, Abc_Random(0) % Vec_IntSize(vValue0)), + Vec_IntEntry(vValue1, Abc_Random(0) % Vec_IntSize(vValue1)) ); + Vec_IntFree( vValue0 ); + Vec_IntFree( vValue1 ); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_SimAbsPerformOne( Gia_Man_t * pGia, word * pOffSet, word * pOnSet, Vec_Wrd_t * vSimsCands, int nWords, int fVerbose ) +{ + abctime clk = Abc_Clock(); + Vec_Int_t * vResub = Vec_IntAlloc( 10 ); + Gia_SimAbsMan_t * p = Gia_SimAbsAlloc( pGia, pOffSet, pOnSet, vSimsCands, nWords, vResub, fVerbose ); + Gia_SimAbsInit( p ); + while ( 1 ) + { + Gia_SimAbsSolve( p ); + if ( !Gia_SimAbsRefine( p ) ) + break; + } + Gia_SimAbsFree( p ); + Abc_PrintTime( 1, "Resubstitution time", Abc_Clock() - clk ); + return vResub; +} + + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +typedef struct Gia_RsbMan_t_ Gia_RsbMan_t; +struct Gia_RsbMan_t_ +{ + Gia_Man_t * pGia; + word * pOffSet; + word * pOnSet; + int nWords; + int nWordsT; + Vec_Wrd_t * vSims; + Vec_Wrd_t * vSimsT; + Vec_Int_t * vCands; + Vec_Int_t * vObjs; + Vec_Int_t * vObjs2; + Vec_Wec_t * vSets[2]; + word * pSet[3]; + Vec_Int_t * vActive; +}; +Gia_RsbMan_t * Gia_RsbAlloc( Gia_Man_t * pGia, word * pOffSet, word * pOnSet, Vec_Wrd_t * vSims, int nWords, Vec_Wrd_t * vSimsT, int nWordsT, Vec_Int_t * vCands ) +{ + int i, iObj; + Gia_RsbMan_t * p = ABC_CALLOC( Gia_RsbMan_t, 1 ); + assert( nWords <= 1024 ); + assert( Vec_WrdSize(vSims) == 64 * nWords * nWordsT ); + assert( Vec_WrdSize(vSims) == Vec_WrdSize(vSimsT) ); + p->pGia = pGia; + p->pOffSet = pOffSet; + p->pOnSet = pOnSet; + p->nWords = nWords; + p->nWordsT = nWordsT; + p->vSims = vSims; + p->vSimsT = vSimsT; + p->vCands = vCands; + p->vObjs = Vec_IntAlloc( 100 ); + p->vObjs2 = Vec_IntAlloc( 100 ); + p->vSets[0] = Vec_WecAlloc( 1024 ); + p->vSets[1] = Vec_WecAlloc( 1024 ); + p->pSet[0] = ABC_CALLOC( word, nWordsT ); + p->pSet[1] = ABC_CALLOC( word, nWordsT ); + p->pSet[2] = ABC_CALLOC( word, nWordsT ); + p->vActive = Vec_IntAlloc( 100 ); + Vec_IntForEachEntry( vCands, iObj, i ) + { + assert( iObj < nWordsT * 64 ); + Abc_TtSetBit( p->pSet[0], iObj ); + } + Vec_WecPushLevel( p->vSets[0] ); + Vec_WecPushLevel( p->vSets[1] ); + for ( i = 0; i < 64*nWords; i++ ) + { + int Value0 = Abc_TtGetBit( pOffSet, i ); + int Value1 = Abc_TtGetBit( pOnSet, i ); + if ( Value0 && !Value1 ) + Vec_WecPush( p->vSets[0], 0, i ); + else if ( !Value0 && Value1 ) + Vec_WecPush( p->vSets[1], 0, i ); + else assert( !Value0 || !Value1 ); + } + assert( Vec_WecSize(p->vSets[0]) == 1 ); + assert( Vec_WecSize(p->vSets[1]) == 1 ); + Abc_Random( 1 ); + //Extra_PrintBinary2( stdout, (unsigned*)pOffSet, 64*nWords ); printf( "\n" ); + //Extra_PrintBinary2( stdout, (unsigned*)pOnSet, 64*nWords ); printf( "\n" ); + return p; +} +void Gia_RsbFree( Gia_RsbMan_t * p ) +{ + Vec_IntFree( p->vActive ); + Vec_IntFree( p->vObjs ); + Vec_IntFree( p->vObjs2 ); + Vec_WecFree( p->vSets[0] ); + Vec_WecFree( p->vSets[1] ); + ABC_FREE( p->pSet[0] ); + ABC_FREE( p->pSet[1] ); + ABC_FREE( p->pSet[2] ); + ABC_FREE( p ); +} + + +int Gia_RsbCost( Gia_RsbMan_t * p ) +{ + Vec_Int_t * vLevel[2]; int i, Cost = 0; + Vec_WecForEachLevelTwo( p->vSets[0], p->vSets[1], vLevel[0], vLevel[1], i ) + Cost += Vec_IntSize(vLevel[0]) * Vec_IntSize(vLevel[1]); + return Cost; +} +void Gia_RsbPrint( Gia_RsbMan_t * p ) +{ + Vec_Int_t * vLevel[2]; + int n, i, nLeaves = 1 << Vec_IntSize(p->vObjs); + assert( Vec_WecSize(p->vSets[0]) == nLeaves ); + assert( Vec_WecSize(p->vSets[1]) == nLeaves ); + printf( "Database for %d objects and cost %d:\n", Vec_IntSize(p->vObjs), Gia_RsbCost(p) ); + Vec_WecForEachLevelTwo( p->vSets[0], p->vSets[1], vLevel[0], vLevel[1], i ) + { + for ( n = 0; n < 2; n++ ) + { + printf( "%5d : ", i ); + Extra_PrintBinary2( stdout, (unsigned*)&i, Vec_IntSize(p->vObjs) ); printf( " %d ", n ); + Vec_IntPrint( vLevel[n] ); + } + } +} +void Gia_RsbUpdateAdd( Gia_RsbMan_t * p, int iObj ) +{ + int n, i, nLeaves = 1 << Vec_IntSize(p->vObjs); + assert( Vec_WecSize(p->vSets[0]) == nLeaves ); + assert( Vec_WecSize(p->vSets[1]) == nLeaves ); + for ( i = 0; i < nLeaves; i++ ) + { + for ( n = 0; n < 2; n++ ) + { + Vec_Int_t * vLevelN = Vec_WecPushLevel(p->vSets[n]); + Vec_Int_t * vLevel = Vec_WecEntry(p->vSets[n], i); + int iMint, j, k = 0; + Vec_IntForEachEntry( vLevel, iMint, j ) + { + if ( Abc_TtGetBit(Vec_WrdEntryP(p->vSims, p->nWords*iObj), iMint) ) + Vec_IntPush( vLevelN, iMint ); + else + Vec_IntWriteEntry( vLevel, k++, iMint ); + } + Vec_IntShrink( vLevel, k ); + } + } + Vec_IntPush( p->vObjs, iObj ); + assert( Vec_WecSize(p->vSets[0]) == 2*nLeaves ); + assert( Vec_WecSize(p->vSets[1]) == 2*nLeaves ); +} +void Gia_RsbUpdateRemove( Gia_RsbMan_t * p, int Index ) +{ + Vec_Int_t * vLevel[2], * vTemp[2][2]; + int k = 0, m, m2, nLeaves = 1 << Vec_IntSize(p->vObjs); + assert( Index < Vec_IntSize(p->vObjs) ); + assert( Vec_WecSize(p->vSets[0]) == nLeaves ); + assert( Vec_WecSize(p->vSets[1]) == nLeaves ); + for ( m = 0; m < nLeaves; m++ ) + { + if ( m & (1 << Index) ) + continue; + m2 = m ^ (1 << Index); + vTemp[0][0] = Vec_WecEntry(p->vSets[0], m); + vTemp[0][1] = Vec_WecEntry(p->vSets[1], m); + vTemp[1][0] = Vec_WecEntry(p->vSets[0], m2); + vTemp[1][1] = Vec_WecEntry(p->vSets[1], m2); + Vec_IntAppend( vTemp[0][0], vTemp[1][0] ); + Vec_IntAppend( vTemp[0][1], vTemp[1][1] ); + Vec_IntClear( vTemp[1][0] ); + Vec_IntClear( vTemp[1][1] ); + } + Vec_IntDrop( p->vObjs, Index ); + Vec_WecForEachLevelTwo( p->vSets[0], p->vSets[1], vLevel[0], vLevel[1], m ) + { + if ( m & (1 << Index) ) + continue; + ABC_SWAP( Vec_Int_t, Vec_WecArray(p->vSets[0])[k], Vec_WecArray(p->vSets[0])[m] ); + ABC_SWAP( Vec_Int_t, Vec_WecArray(p->vSets[1])[k], Vec_WecArray(p->vSets[1])[m] ); + k++; + } + assert( k == nLeaves/2 ); + Vec_WecShrink( p->vSets[0], k ); + Vec_WecShrink( p->vSets[1], k ); +} +int Gia_RsbRemovalCost( Gia_RsbMan_t * p, int Index ) +{ + Vec_Int_t * vTemp[2][2]; + //unsigned Mask = Abc_InfoMask( Index ); + int m, m2, Cost = 0, nLeaves = 1 << Vec_IntSize(p->vObjs); + assert( Vec_WecSize(p->vSets[0]) == (1 << Vec_IntSize(p->vObjs)) ); + assert( Vec_WecSize(p->vSets[1]) == (1 << Vec_IntSize(p->vObjs)) ); + for ( m = 0; m < nLeaves; m++ ) + { + if ( m & (1 << Index) ) + continue; + m2 = m ^ (1 << Index); + vTemp[0][0] = Vec_WecEntry(p->vSets[0], m); + vTemp[0][1] = Vec_WecEntry(p->vSets[1], m); + vTemp[1][0] = Vec_WecEntry(p->vSets[0], m2); + vTemp[1][1] = Vec_WecEntry(p->vSets[1], m2); + Cost += (Vec_IntSize(vTemp[0][0]) + Vec_IntSize(vTemp[1][0])) * (Vec_IntSize(vTemp[0][1]) + Vec_IntSize(vTemp[1][1])); + } + return Cost; +} +int Gia_RsbFindNodeToRemove( Gia_RsbMan_t * p, int * pMinCost ) +{ + int i, iObj, iMin = -1, CostMin = ABC_INFINITY; + Vec_IntForEachEntry( p->vObjs, iObj, i ) + { + int Cost = Gia_RsbRemovalCost( p, i ); + if ( CostMin > Cost ) + { + CostMin = Cost; + iMin = i; + } + } + if ( pMinCost ) + *pMinCost = CostMin; + return iMin; +} + +void Gia_RsbFindMints( Gia_RsbMan_t * p, int * pMint0, int * pMint1 ) +{ + int iSetI = Abc_Random(0) % Vec_IntSize(p->vActive); + int iSet = Vec_IntEntry( p->vActive, iSetI ); + Vec_Int_t * vArray0 = Vec_WecEntry(p->vSets[0], iSet); + Vec_Int_t * vArray1 = Vec_WecEntry(p->vSets[1], iSet); + int iMint0i = Abc_Random(0) % Vec_IntSize(vArray0); + int iMint1i = Abc_Random(0) % Vec_IntSize(vArray1); + int iMint0 = Vec_IntEntry( vArray0, iMint0i ); + int iMint1 = Vec_IntEntry( vArray1, iMint1i ); + *pMint0 = iMint0; + *pMint1 = iMint1; +} +int Gia_RsbFindNode( Gia_RsbMan_t * p ) +{ + int i, iObj, nNodes, nNodesNew = -1, nNodesOld = -1, Mint0, Mint1, Shift; + Abc_TtCopy( p->pSet[1], p->pSet[0], p->nWordsT, 0 ); + Vec_IntForEachEntry( p->vObjs, iObj, i ) + { + assert( Abc_TtGetBit(p->pSet[1], iObj) ); + Abc_TtXorBit(p->pSet[1], iObj); + } + Abc_TtCopy( p->pSet[2], p->pSet[1], p->nWordsT, 0 ); + Gia_RsbFindMints( p, &Mint0, &Mint1 ); + nNodes = Abc_TtAndXorSum( p->pSet[1], Vec_WrdEntryP(p->vSimsT, p->nWordsT*Mint0), Vec_WrdEntryP(p->vSimsT, p->nWordsT*Mint1), p->nWordsT ); + for ( i = 0; i < 5 && nNodes > 1; i++ ) + { + nNodesOld = nNodes; + Abc_TtCopy( p->pSet[2], p->pSet[1], p->nWordsT, 0 ); + Gia_RsbFindMints( p, &Mint0, &Mint1 ); + nNodesNew = Abc_TtAndXorSum( p->pSet[1], Vec_WrdEntryP(p->vSimsT, p->nWordsT*Mint0), Vec_WrdEntryP(p->vSimsT, p->nWordsT*Mint1), p->nWordsT ); + assert( nNodesNew <= nNodes ); + if ( nNodesNew < nNodes ) + i = 0; + nNodes = nNodesNew; + } + Shift = Abc_Random(0) % (64*p->nWordsT); + for ( i = 0; i < 64*p->nWordsT; i++ ) + { + int Index = (i+Shift) % (64*p->nWordsT); + if ( Abc_TtGetBit( p->pSet[2], Index ) ) + return Index; + } + assert( 0 ); + return -1; +} +int Gia_RsbCollectValid( Gia_RsbMan_t * p ) +{ + Vec_Int_t * vLevel[2]; int i; + Vec_IntClear( p->vActive ); + assert( Vec_WecSize(p->vSets[0]) == Vec_WecSize(p->vSets[1]) ); + Vec_WecForEachLevelTwo( p->vSets[0], p->vSets[1], vLevel[0], vLevel[1], i ) + if ( Vec_IntSize(vLevel[0]) && Vec_IntSize(vLevel[1]) ) + Vec_IntPush( p->vActive, i ); + if ( Vec_IntSize(p->vActive) == 0 ) + return 0; + return 1; +} +Vec_Int_t * Gia_RsbSolve( Gia_RsbMan_t * p ) +{ + int i, iMin; + Vec_IntClear( p->vObjs ); + while ( Gia_RsbCollectValid(p) ) + Gia_RsbUpdateAdd( p, Gia_RsbFindNode(p) ); + for ( i = 0; i < 100; i++ ) + { + int k, nUndo = 1 + Abc_Random(0) % Vec_IntSize(p->vObjs); + for ( k = 0; k < nUndo; k++ ) + { + iMin = Gia_RsbFindNodeToRemove( p, NULL );// &MinCost ); + Gia_RsbUpdateRemove( p, iMin ); + } + while ( Gia_RsbCollectValid(p) ) + Gia_RsbUpdateAdd( p, Gia_RsbFindNode(p) ); + if ( Vec_IntSize(p->vObjs2) == 0 || Vec_IntSize(p->vObjs2) > Vec_IntSize(p->vObjs) ) + { + Vec_IntClear( p->vObjs2 ); + Vec_IntAppend( p->vObjs2, p->vObjs ); + } + } + //Gia_RsbPrint( p ); + return Vec_IntDup( p->vObjs2 ); +} +Vec_Int_t * Gia_RsbSetFind( word * pOffSet, word * pOnSet, Vec_Wrd_t * vSims, int nWords, Vec_Wrd_t * vSimsT, int nWordsT, Vec_Int_t * vCands ) +{ + Gia_RsbMan_t * p = Gia_RsbAlloc( NULL, pOffSet, pOnSet, vSims, nWords, vSimsT, nWordsT, vCands ); + Vec_Int_t * vObjs = Gia_RsbSolve( p ); + Gia_RsbFree( p ); + Vec_IntSort( vObjs, 0 ); + return vObjs; +} + +/**Function************************************************************* + + Synopsis [Improving quality of simulation patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_SimQualityOne( Gia_Man_t * p, Vec_Int_t * vPat, int fPoOnly ) +{ + int i, Id, Value, nWords = Abc_Bit6WordNum( 1+Gia_ManCiNum(p) ); + Vec_Wrd_t * vTemp, * vSims, * vSimsPi = Vec_WrdStart( Gia_ManCiNum(p) * nWords ); + Vec_Int_t * vRes; + assert( Vec_IntSize(vPat) == Gia_ManCiNum(p) ); + Vec_IntForEachEntry( vPat, Value, i ) + { + word * pSim = Vec_WrdEntryP( vSimsPi, i*nWords ); + if ( Value ) + Abc_TtFill( pSim, nWords ); + Abc_TtXorBit( pSim, i+1 ); + } + vTemp = p->vSimsPi; + p->vSimsPi = vSimsPi; + vSims = Gia_ManSimPatSim( p ); + p->vSimsPi = vTemp; + if ( fPoOnly ) + { + vRes = Vec_IntStart( Gia_ManCoNum(p) ); + Gia_ManForEachCoId( p, Id, i ) + { + word * pSim = Vec_WrdEntryP( vSims, Id*nWords ); + if ( pSim[0] & 1 ) + Abc_TtNot( pSim, nWords ); + Vec_IntWriteEntry( vRes, i, Abc_TtCountOnesVec(pSim, nWords) ); + } + assert( Vec_IntSize(vRes) == Gia_ManCoNum(p) ); + } + else + { + vRes = Vec_IntStart( Gia_ManObjNum(p) ); + Gia_ManForEachAndId( p, Id ) + { + word * pSim = Vec_WrdEntryP( vSims, Id*nWords ); + if ( pSim[0] & 1 ) + Abc_TtNot( pSim, nWords ); + Vec_IntWriteEntry( vRes, Id, Abc_TtCountOnesVec(pSim, nWords) ); + } + assert( Vec_IntSize(vRes) == Gia_ManObjNum(p) ); + } + Vec_WrdFree( vSims ); + Vec_WrdFree( vSimsPi ); + return vRes; +} +void Gia_SimQualityTest( Gia_Man_t * p ) +{ + Vec_Int_t * vPat, * vRes; + int k, m, nMints = (1 << Gia_ManCiNum(p)); + assert( Gia_ManCiNum(p) <= 10 ); + for ( m = 0; m < nMints; m++ ) + { + printf( "%d : ", m ); + Extra_PrintBinary( stdout, (unsigned*)&m, Gia_ManCiNum(p) ); + printf( " " ); + vPat = Vec_IntAlloc( Gia_ManCiNum(p) ); + for ( k = 0; k < Gia_ManCiNum(p); k++ ) + Vec_IntPush( vPat, (m >> k) & 1 ); + vRes = Gia_SimQualityOne( p, vPat, 1 ); + printf( "%d ", Vec_IntSum(vRes) ); + Vec_IntFree( vRes ); + Vec_IntFree( vPat ); + printf( "\n" ); + } +} +Vec_Int_t * Gia_SimGenerateStats( Gia_Man_t * p ) +{ + Vec_Int_t * vTotal = Vec_IntStart( Gia_ManObjNum(p) ); + Vec_Int_t * vRes, * vPat; + int i, k, Value; + Abc_Random(1); + for ( i = 0; i < 1000; i++ ) + { + vPat = Vec_IntAlloc( Gia_ManCiNum(p) ); + for ( k = 0; k < Gia_ManCiNum(p); k++ ) + Vec_IntPush( vPat, Abc_Random(0) & 1 ); + vRes = Gia_SimQualityOne( p, vPat, 0 ); + assert( Vec_IntSize(vRes) == Gia_ManObjNum(p) ); + Vec_IntForEachEntry( vRes, Value, k ) + Vec_IntAddToEntry( vTotal, k, Value ); + Vec_IntFree( vRes ); + Vec_IntFree( vPat ); + } + //Vec_IntPrint( vTotal ); + return vTotal; +} +double Gia_SimComputeScore( Gia_Man_t * p, Vec_Int_t * vTotal, Vec_Int_t * vThis ) +{ + double TotalScore = 0; + int i, Total, This; + assert( Vec_IntSize(vTotal) == Vec_IntSize(vThis) ); + Vec_IntForEachEntryTwo( vTotal, vThis, Total, This, i ) + { + if ( Total == 0 ) + Total = 1; + TotalScore += 1000.0*This/Total; + } + return TotalScore == 0 ? 1.0 : TotalScore/Gia_ManAndNum(p); +} +int Gia_SimQualityPatternsMax( Gia_Man_t * p, Vec_Int_t * vPat, int Iter, int fVerbose, Vec_Int_t * vStats ) +{ + int k, MaxIn = -1; + Vec_Int_t * vTries = Vec_IntAlloc( 100 ); + Vec_Int_t * vRes = Gia_SimQualityOne( p, vPat, 0 ); + double Value, InitValue, MaxValue = InitValue = Gia_SimComputeScore( p, vStats, vRes ); + Vec_IntFree( vRes ); + + if ( fVerbose ) + printf( "Iter %5d : Init = %6.3f ", Iter, InitValue ); + + for ( k = 0; k < Gia_ManCiNum(p); k++ ) + { + Vec_IntArray(vPat)[k] ^= 1; + //Vec_IntPrint( vPat ); + + vRes = Gia_SimQualityOne( p, vPat, 0 ); + Value = Gia_SimComputeScore( p, vStats, vRes ); + if ( MaxValue <= Value ) + { + if ( MaxValue < Value ) + Vec_IntClear( vTries ); + Vec_IntPush( vTries, k ); + MaxValue = Value; + MaxIn = k; + } + Vec_IntFree( vRes ); + + Vec_IntArray(vPat)[k] ^= 1; + } + MaxIn = Vec_IntSize(vTries) ? Vec_IntEntry( vTries, rand()%Vec_IntSize(vTries) ) : -1; + if ( fVerbose ) + { + printf( "Final = %6.3f Ratio = %4.2f Tries = %5d ", MaxValue, MaxValue/InitValue, Vec_IntSize(vTries) ); + printf( "Choosing %5d\r", MaxIn ); + } + Vec_IntFree( vTries ); + return MaxIn; +} +Vec_Int_t * Gia_ManPatCollectOne( Gia_Man_t * p, Vec_Wrd_t * vPatterns, int n, int nWords ) +{ + Vec_Int_t * vPat = Vec_IntAlloc( Gia_ManCiNum(p) ); int k; + for ( k = 0; k < Gia_ManCiNum(p); k++ ) + Vec_IntPush( vPat, Abc_TtGetBit( Vec_WrdEntryP(vPatterns, k*nWords), n ) ); + return vPat; +} +void Gia_ManPatUpdateOne( Gia_Man_t * p, Vec_Wrd_t * vPatterns, int n, int nWords, Vec_Int_t * vPat ) +{ + int k, Value; + Vec_IntForEachEntry( vPat, Value, k ) + { + word * pSim = Vec_WrdEntryP( vPatterns, k*nWords ); + if ( Abc_TtGetBit(pSim, n) != Value ) + Abc_TtXorBit( pSim, n ); + } +} +void Gia_ManPatDistImprove( Gia_Man_t * p, int fVerbose ) +{ + int n, k, nWords = Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p); + double InitValue, InitTotal = 0, FinalValue, FinalTotal = 0; + Vec_Int_t * vPat, * vRes, * vStats = Gia_SimGenerateStats( p ); + Vec_Wrd_t * vPatterns = p->vSimsPi; p->vSimsPi = NULL; + Abc_Random(1); + for ( n = 0; n < 64*nWords; n++ ) + { + abctime clk = Abc_Clock(); +// if ( n == 32 ) +// break; + + vPat = Gia_ManPatCollectOne( p, vPatterns, n, nWords ); + vRes = Gia_SimQualityOne( p, vPat, 0 ); + InitValue = Gia_SimComputeScore(p, vStats, vRes); + InitTotal += InitValue; + Vec_IntFree( vRes ); + + for ( k = 0; k < 100; k++ ) + { + int MaxIn = Gia_SimQualityPatternsMax( p, vPat, k, fVerbose, vStats ); + if ( MaxIn == -1 ) + break; + assert( MaxIn >= 0 && MaxIn < Gia_ManCiNum(p) ); + Vec_IntArray(vPat)[MaxIn] ^= 1; + } + //Vec_IntPrint( vPat ); + + vRes = Gia_SimQualityOne( p, vPat, 0 ); + FinalValue = Gia_SimComputeScore(p, vStats, vRes); + FinalTotal += FinalValue; + Vec_IntFree( vRes ); + + if ( fVerbose ) + { + printf( "Pat %5d : Tries = %5d InitValue = %6.3f FinalValue = %6.3f Ratio = %4.2f ", + n, k, InitValue, FinalValue, FinalValue/InitValue ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } + + Gia_ManPatUpdateOne( p, vPatterns, n, nWords, vPat ); + Vec_IntFree( vPat ); + } + Vec_IntFree( vStats ); + if ( fVerbose ) + printf( "\n" ); + printf( "Improved %d patterns with average init value %.2f and average final value %.2f.\n", + 64*nWords, 1.0*InitTotal/(64*nWords), 1.0*FinalTotal/(64*nWords) ); + p->vSimsPi = vPatterns; +} + +/**Function************************************************************* + + Synopsis [Improving quality of simulation patterns.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Gia_SimCollectRare( Gia_Man_t * p, Vec_Wrd_t * vPatterns, int RareLimit ) +{ + Vec_Int_t * vRareCounts = Vec_IntAlloc( 100 ); // (node, rare_count) pairs + int Id, nWords = Vec_WrdSize(vPatterns) / Gia_ManCiNum(p), TotalBits = 64*nWords; + Vec_Wrd_t * vSims, * vTemp = p->vSimsPi; + assert( Vec_WrdSize(vPatterns) % Gia_ManCiNum(p) == 0 ); + p->vSimsPi = vPatterns; + vSims = Gia_ManSimPatSim( p ); + p->vSimsPi = vTemp; + Gia_ManForEachAndId( p, Id ) + { + word * pSim = Vec_WrdEntryP( vSims, Id*nWords ); + int Count = Abc_TtCountOnesVec( pSim, nWords ); + int fRareOne = Count < TotalBits/2; // fRareOne is 1 if rare value is 1 + int CountRare = fRareOne ? Count : TotalBits - Count; + assert( CountRare <= TotalBits/2 ); + if ( CountRare <= RareLimit ) + Vec_IntPushTwo( vRareCounts, Abc_Var2Lit(Id, fRareOne), CountRare ); + } + Vec_WrdFree( vSims ); + return vRareCounts; +} +Vec_Flt_t * Gia_SimQualityImpact( Gia_Man_t * p, Vec_Int_t * vPat, Vec_Int_t * vRareCounts ) +{ + Vec_Flt_t * vQuoIncs = Vec_FltStart( Gia_ManCiNum(p) ); + int nWordsNew = Abc_Bit6WordNum( 1+Gia_ManCiNum(p) ); + Vec_Wrd_t * vSimsPiNew = Vec_WrdStart( Gia_ManCiNum(p) * nWordsNew ); + Vec_Wrd_t * vTemp, * vSims; + int i, k, Value, RareLit, RareCount; + assert( Vec_IntSize(vPat) == Gia_ManCiNum(p) ); + Vec_IntForEachEntry( vPat, Value, i ) + { + word * pSim = Vec_WrdEntryP( vSimsPiNew, i*nWordsNew ); + if ( Value ) + Abc_TtFill( pSim, nWordsNew ); + Abc_TtXorBit( pSim, i+1 ); + } + vTemp = p->vSimsPi; + p->vSimsPi = vSimsPiNew; + vSims = Gia_ManSimPatSim( p ); + p->vSimsPi = vTemp; + Vec_IntForEachEntryDouble( vRareCounts, RareLit, RareCount, i ) + { + float Incrm = (float)1.0/(RareCount+1); + int RareObj = Abc_Lit2Var(RareLit); + int RareVal = Abc_LitIsCompl(RareLit); + word * pSim = Vec_WrdEntryP( vSims, RareObj*nWordsNew ); + int OrigVal = pSim[0] & 1; + if ( OrigVal ) + Abc_TtNot( pSim, nWordsNew ); + for ( k = 0; k < Gia_ManCiNum(p); k++ ) + if ( Abc_TtGetBit(pSim, k+1) ) // value changed + Vec_FltAddToEntry( vQuoIncs, k, OrigVal != RareVal ? Incrm : -Incrm ); + } + Vec_WrdFree( vSims ); + Vec_WrdFree( vSimsPiNew ); + return vQuoIncs; +} +Vec_Int_t * Gia_SimCollectBest( Vec_Flt_t * vQuo ) +{ + Vec_Int_t * vRes; int i; + float Value, ValueMax = Vec_FltFindMax( vQuo ); + if ( ValueMax <= 0 ) + return NULL; + vRes = Vec_IntAlloc( 100 ); // variables with max quo + Vec_FltForEachEntry( vQuo, Value, i ) + if ( Value == ValueMax ) + Vec_IntPush( vRes, i ); + return vRes; +} +float Gia_ManPatGetQuo( Gia_Man_t * p, Vec_Int_t * vRareCounts, Vec_Wrd_t * vSims, int n, int nWords ) +{ + float Quality = 0; + int RareLit, RareCount, i; + assert( Vec_WrdSize(vSims) == Gia_ManObjNum(p) ); + Vec_IntForEachEntryDouble( vRareCounts, RareLit, RareCount, i ) + { + float Incrm = (float)1.0/(RareCount+1); + int RareObj = Abc_Lit2Var(RareLit); + int RareVal = Abc_LitIsCompl(RareLit); + word * pSim = Vec_WrdEntryP( vSims, RareObj*nWords ); + if ( Abc_TtGetBit(pSim, n) == RareVal ) + Quality += Incrm; + } + return Quality; +} +float Gia_ManPatGetTotalQuo( Gia_Man_t * p, int RareLimit, Vec_Wrd_t * vPatterns, int nWords ) +{ + float Total = 0; int n; + Vec_Int_t * vRareCounts = Gia_SimCollectRare( p, vPatterns, RareLimit ); + Vec_Wrd_t * vSims, * vTemp = p->vSimsPi; + p->vSimsPi = vPatterns; + vSims = Gia_ManSimPatSim( p ); + p->vSimsPi = vTemp; + for ( n = 0; n < 64*nWords; n++ ) + Total += Gia_ManPatGetQuo( p, vRareCounts, vSims, n, nWords ); + Vec_IntFree( vRareCounts ); + Vec_WrdFree( vSims ); + return Total; +} +float Gia_ManPatGetOneQuo( Gia_Man_t * p, int RareLimit, Vec_Wrd_t * vPatterns, int nWords, int n ) +{ + float Total = 0; + Vec_Int_t * vRareCounts = Gia_SimCollectRare( p, vPatterns, RareLimit ); + Vec_Wrd_t * vSims, * vTemp = p->vSimsPi; + p->vSimsPi = vPatterns; + vSims = Gia_ManSimPatSim( p ); + p->vSimsPi = vTemp; + Total += Gia_ManPatGetQuo( p, vRareCounts, vSims, n, nWords ); + Vec_IntFree( vRareCounts ); + Vec_WrdFree( vSims ); + return Total; +} +void Gia_ManPatRareImprove( Gia_Man_t * p, int RareLimit, int fVerbose ) +{ + abctime clk = Abc_Clock(); + float FinalTotal, InitTotal; + int n, nRares = 0, nChanges = 0, nWords = Vec_WrdSize(p->vSimsPi) / Gia_ManCiNum(p); + Vec_Wrd_t * vPatterns = p->vSimsPi; p->vSimsPi = NULL; + InitTotal = Gia_ManPatGetTotalQuo( p, RareLimit, vPatterns, nWords ); + for ( n = 0; n < 64*nWords; n++ ) + { + abctime clk = Abc_Clock(); + Vec_Int_t * vRareCounts = Gia_SimCollectRare( p, vPatterns, RareLimit ); + Vec_Int_t * vPat = Gia_ManPatCollectOne( p, vPatterns, n, nWords ); + Vec_Flt_t * vQuoIncs = Gia_SimQualityImpact( p, vPat, vRareCounts ); + Vec_Int_t * vBest = Gia_SimCollectBest( vQuoIncs ); + if ( fVerbose ) + { + float PatQuo = Gia_ManPatGetOneQuo( p, RareLimit, vPatterns, nWords, n ); + printf( "Pat %5d : Rare = %4d Cands = %3d Value = %8.3f Change = %8.3f ", + n, Vec_IntSize(vRareCounts)/2, vBest ? Vec_IntSize(vBest) : 0, + PatQuo, vBest ? Vec_FltEntry(vQuoIncs, Vec_IntEntry(vBest,0)) : 0 ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); + } + if ( vBest != NULL ) + { + int VarBest = Vec_IntEntry( vBest, rand()%Vec_IntSize(vBest) ); + Abc_TtXorBit( Vec_WrdEntryP(vPatterns, VarBest*nWords), n ); + nChanges++; + } + nRares = Vec_IntSize(vRareCounts)/2; + Vec_IntFree( vRareCounts ); + Vec_IntFree( vPat ); + Vec_FltFree( vQuoIncs ); + Vec_IntFreeP( &vBest ); + } + if ( fVerbose ) + printf( "\n" ); + FinalTotal = Gia_ManPatGetTotalQuo( p, RareLimit, vPatterns, nWords ); + p->vSimsPi = vPatterns; + + printf( "Improved %d out of %d patterns using %d rare nodes: %.2f -> %.2f. ", + nChanges, 64*nWords, nRares, InitTotal, FinalTotal ); + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/aig/gia/giaStr.c b/src/aig/gia/giaStr.c index 68d478b8..085738c3 100644 --- a/src/aig/gia/giaStr.c +++ b/src/aig/gia/giaStr.c @@ -1357,7 +1357,7 @@ Gia_Man_t * Str_NtkBalance( Gia_Man_t * pGia, Str_Ntk_t * p, int nLutSize, int f ABC_FREE( pNew->vCopies.pArray ); Gia_ManHashStop( pNew ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia) ); - pNew = Gia_ManDupNoMuxes( pTemp = pNew ); + pNew = Gia_ManDupNoMuxes( pTemp = pNew, 0 ); Gia_ManStop( pTemp ); // if ( pGia->pManTime != NULL ) // pNew->pManTime = Tim_ManDup( (Tim_Man_t *)pGia->pManTime, 0 ); diff --git a/src/aig/gia/giaSweep.c b/src/aig/gia/giaSweep.c index 2d8e705b..1d66caee 100644 --- a/src/aig/gia/giaSweep.c +++ b/src/aig/gia/giaSweep.c @@ -203,6 +203,7 @@ Gia_Man_t * Gia_ManDupWithBoxes( Gia_Man_t * p, int fSeq ) pNew->pAigExtra = Gia_ManUpdateExtraAig2( p->pManTime, p->pAigExtra, vBoxesLeft ); assert( Gia_ManCiNum(pNew) == Tim_ManPiNum((Tim_Man_t*)pNew->pManTime) + Gia_ManCoNum(pNew->pAigExtra) ); Vec_IntFree( vBoxesLeft ); + pNew->nAnd2Delay = p->nAnd2Delay; return pNew; } diff --git a/src/aig/gia/giaTruth.c b/src/aig/gia/giaTruth.c index 2062f2ad..91c4fa24 100644 --- a/src/aig/gia/giaTruth.c +++ b/src/aig/gia/giaTruth.c @@ -83,7 +83,159 @@ word Gia_LutComputeTruth6Simple( Gia_Man_t * p, int iPo ) Gia_Obj_t * pObj = Gia_ManPo( p, iPo ); word Truth = Gia_LutComputeTruth6Simple_rec( p, Gia_ObjFaninId0p(p, pObj) ); return Gia_ObjFaninC0(pObj) ? ~Truth : Truth; +} + +word Gia_LutComputeTruth6Map_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vMap ) +{ + word Truth0, Truth1, Truth; + Gia_Obj_t * pObj = Gia_ManObj(p, iObj); + if ( Gia_ObjIsConst0(pObj) ) + return 0; + if ( Gia_ObjIsCi(pObj) ) + return s_Truths6[Vec_IntEntry(vMap, Gia_ObjCioId(pObj))]; + Truth0 = Gia_LutComputeTruth6Map_rec( p, Gia_ObjFaninId0(pObj, iObj), vMap ); + Truth1 = Gia_LutComputeTruth6Map_rec( p, Gia_ObjFaninId1(pObj, iObj), vMap ); + Truth0 = Gia_ObjFaninC0(pObj) ? ~Truth0 : Truth0; + Truth1 = Gia_ObjFaninC1(pObj) ? ~Truth1 : Truth1; + Truth = Gia_ObjIsXor(pObj) ? Truth0 ^ Truth1 : Truth0 & Truth1; + return Truth; +} +word Gia_LutComputeTruth6Map( Gia_Man_t * p, int iPo, Vec_Int_t * vMap ) +{ + Gia_Obj_t * pObj = Gia_ManPo( p, iPo ); + word Truth = Gia_LutComputeTruth6Map_rec( p, Gia_ObjFaninId0p(p, pObj), vMap ); + return Gia_ObjFaninC0(pObj) ? ~Truth : Truth; +} + +/**Function************************************************************* + + Synopsis [Generate MUX tree of the truth table.] + + Description [] + + SideEffects [] + SeeAlso [] + +***********************************************************************/ +static unsigned s_Truths5[5] = { + 0xAAAAAAAA, + 0xCCCCCCCC, + 0xF0F0F0F0, + 0xFF00FF00, + 0xFFFF0000, +}; +static inline int Abc_Tt5HasVar( unsigned t, int iVar ) +{ + return ((t << (1<<iVar)) & s_Truths5[iVar]) != (t & s_Truths5[iVar]); +} +static inline unsigned Abc_Tt5Cofactor0( unsigned t, int iVar ) +{ + assert( iVar >= 0 && iVar < 6 ); + return (t & ~s_Truths5[iVar]) | ((t & ~s_Truths5[iVar]) << (1<<iVar)); +} +static inline unsigned Abc_Tt5Cofactor1( unsigned t, int iVar ) +{ + assert( iVar >= 0 && iVar < 6 ); + return (t & s_Truths5[iVar]) | ((t & s_Truths5[iVar]) >> (1<<iVar)); +} +int Gia_Truth5ToGia( Gia_Man_t * p, int * pVarLits, int nVars, unsigned Truth, int fHash ) +{ + int Var, Lit0, Lit1; + if ( Truth == 0 ) + return 0; + if ( ~Truth == 0 ) + return 1; + assert( nVars > 0 ); + // find the topmost var + for ( Var = nVars-1; Var >= 0; Var-- ) + if ( Abc_Tt5HasVar( Truth, Var ) ) + break; + assert( Var >= 0 ); + // cofactor + Lit0 = Gia_Truth5ToGia( p, pVarLits, Var, Abc_Tt5Cofactor0(Truth, Var), fHash ); + Lit1 = Gia_Truth5ToGia( p, pVarLits, Var, Abc_Tt5Cofactor1(Truth, Var), fHash ); + if ( fHash ) + return Gia_ManHashMux( p, pVarLits[Var], Lit1, Lit0 ); + else + return Gia_ManAppendMux( p, pVarLits[Var], Lit1, Lit0 ); +} + +/**Function************************************************************* + + Synopsis [Generate MUX tree of the truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Gia_Truth6ToGia( Gia_Man_t * p, int * pVarLits, int nVars, word Truth, int fHash ) +{ + int Var, Lit0, Lit1; + if ( Truth == 0 ) + return 0; + if ( ~Truth == 0 ) + return 1; + assert( nVars > 0 ); + // find the topmost var + for ( Var = nVars-1; Var >= 0; Var-- ) + if ( Abc_Tt6HasVar( Truth, Var ) ) + break; + assert( Var >= 0 ); + // cofactor + Lit0 = Gia_Truth6ToGia( p, pVarLits, Var, Abc_Tt6Cofactor0(Truth, Var), fHash ); + Lit1 = Gia_Truth6ToGia( p, pVarLits, Var, Abc_Tt6Cofactor1(Truth, Var), fHash ); + if ( fHash ) + return Gia_ManHashMux( p, pVarLits[Var], Lit1, Lit0 ); + else + return Gia_ManAppendMux( p, pVarLits[Var], Lit1, Lit0 ); +} +void Gia_Truth6ToGiaTest( Gia_Man_t * p ) +{ + int Size = 5; + word Truth, TruthNew; + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManCiNum(p) ); + Vec_Int_t * vSupp = Vec_IntStart( 100 ); + int nCos = Gia_ManCoNum(p), Count = 0; + int i, k, Id, ObjId, iLitNew; + Gia_ManHashAlloc( p ); + Gia_ManForEachCoId( p, Id, i ) + { + Gia_ManCollectCis( p, &Id, 1, vSupp ); // ObjIds + if ( Vec_IntSize(vSupp) <= Size && i < nCos ) + { + int pVarLits[6]; + Vec_IntForEachEntry( vSupp, ObjId, k ) + { + int CioId = Gia_ObjCioId(Gia_ManObj(p, ObjId)); + Vec_IntWriteEntry( vMap, CioId, k ); + pVarLits[k] = Abc_Var2Lit( ObjId, 0 ); + } + Truth = Gia_LutComputeTruth6Map( p, i, vMap ); + if ( Size == 5 ) + iLitNew = Gia_Truth5ToGia( p, pVarLits, Vec_IntSize(vSupp), (unsigned)Truth, 1 ); + else + iLitNew = Gia_Truth6ToGia( p, pVarLits, Vec_IntSize(vSupp), Truth, 1 ); + Gia_ManAppendCo( p, iLitNew ); + TruthNew = Gia_LutComputeTruth6Map( p, Gia_ManCoNum(p)-1, vMap ); + Vec_IntForEachEntry( vSupp, ObjId, k ) + { + int CioId = Gia_ObjCioId(Gia_ManObj(p, ObjId)); + Vec_IntWriteEntry( vMap, CioId, -1 ); + } + if ( Truth != TruthNew ) + printf( "Error for output %d.\n", i ); + Count++; + //Dau_DsdPrintFromTruth( &Truth, Vec_IntSize(vSupp) ); + } + } + Gia_ManHashStop( p ); + printf( "Finished processing %d outputs.\n", Count ); + Vec_IntFree( vSupp ); + Vec_IntFree( vMap ); } /**Function************************************************************* diff --git a/src/aig/gia/giaUtil.c b/src/aig/gia/giaUtil.c index ea6cb147..d0ec969f 100644 --- a/src/aig/gia/giaUtil.c +++ b/src/aig/gia/giaUtil.c @@ -694,7 +694,8 @@ void Gia_ManCreateValueRefs( Gia_Man_t * p ) if ( Gia_ObjIsAnd(pObj) ) { Gia_ObjFanin0(pObj)->Value++; - Gia_ObjFanin1(pObj)->Value++; + if ( !Gia_ObjIsBuf(pObj) ) + Gia_ObjFanin1(pObj)->Value++; } else if ( Gia_ObjIsCo(pObj) ) Gia_ObjFanin0(pObj)->Value++; @@ -723,7 +724,8 @@ void Gia_ManCreateRefs( Gia_Man_t * p ) if ( Gia_ObjIsAnd(pObj) ) { Gia_ObjRefFanin0Inc( p, pObj ); - Gia_ObjRefFanin1Inc( p, pObj ); + if ( !Gia_ObjIsBuf(pObj) ) + Gia_ObjRefFanin1Inc( p, pObj ); if ( Gia_ObjIsMuxId(p, i) ) Gia_ObjRefFanin2Inc( p, pObj ); } @@ -2223,167 +2225,6 @@ void Gia_ManUpdateCopy( Vec_Int_t * vCopy, Gia_Man_t * p ) /**Function************************************************************* - Synopsis [Populate internal simulation info.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline word * Gia_ManObjSim( Gia_Man_t * p, int iObj ) -{ - return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); -} -static inline void Gia_ManObjSimPi( Gia_Man_t * p, int iObj ) -{ - int w; - word * pSim = Gia_ManObjSim( p, iObj ); - for ( w = 0; w < p->nSimWords; w++ ) - pSim[w] = Gia_ManRandomW( 0 ); -// pSim[0] <<= 1; -} -static inline void Gia_ManObjSimPo( Gia_Man_t * p, int iObj ) -{ - int w; - Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); - word * pSimCo = Gia_ManObjSim( p, iObj ); - word * pSimDri = Gia_ManObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); - if ( Gia_ObjFaninC0(pObj) ) - for ( w = 0; w < p->nSimWords; w++ ) - pSimCo[w] = ~pSimDri[w]; - else - for ( w = 0; w < p->nSimWords; w++ ) - pSimCo[w] = pSimDri[w]; -} -static inline void Gia_ManObjSimAnd( Gia_Man_t * p, int iObj ) -{ - int w; - Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); - word * pSim = Gia_ManObjSim( p, iObj ); - word * pSim0 = Gia_ManObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); - word * pSim1 = Gia_ManObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); - if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->nSimWords; w++ ) - pSim[w] = ~pSim0[w] & ~pSim1[w]; - else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->nSimWords; w++ ) - pSim[w] = ~pSim0[w] & pSim1[w]; - else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) - for ( w = 0; w < p->nSimWords; w++ ) - pSim[w] = pSim0[w] & ~pSim1[w]; - else - for ( w = 0; w < p->nSimWords; w++ ) - pSim[w] = pSim0[w] & pSim1[w]; -} -int Gia_ManSimulateWords( Gia_Man_t * p, int nWords ) -{ - Gia_Obj_t * pObj; int i; - // allocate simulation info for one timeframe - Vec_WrdFreeP( &p->vSims ); - p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords ); - p->nSimWords = nWords; - // perform simulation - Gia_ManForEachObj1( p, pObj, i ) - { - if ( Gia_ObjIsAnd(pObj) ) - Gia_ManObjSimAnd( p, i ); - else if ( Gia_ObjIsCi(pObj) ) - Gia_ManObjSimPi( p, i ); - else if ( Gia_ObjIsCo(pObj) ) - Gia_ManObjSimPo( p, i ); - else assert( 0 ); - } - return 1; -} - - -/**Function************************************************************* - - Synopsis [Dump data files.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Gia_ManDumpFiles( Gia_Man_t * p, int nCexesT, int nCexesV ) -{ - int n, nSize[2] = {nCexesT*64, nCexesV*64}; - - char pFileNameOutTX[100]; - char pFileNameOutTY[100]; - char pFileNameOutVX[100]; - char pFileNameOutVY[100]; - - sprintf( pFileNameOutTX, "data/%s_%d_%d.data", Gia_ManName(p), nSize[0], Gia_ManCiNum(p) ); - sprintf( pFileNameOutTY, "data/%s_%d_%d.data", Gia_ManName(p), nSize[0], Gia_ManCoNum(p) ); - sprintf( pFileNameOutVX, "data/%s_%d_%d.data", Gia_ManName(p), nSize[1], Gia_ManCiNum(p) ); - sprintf( pFileNameOutVY, "data/%s_%d_%d.data", Gia_ManName(p), nSize[1], Gia_ManCoNum(p) ); - - Gia_ManRandomW( 1 ); - for ( n = 0; n < 2; n++ ) - { - int Res = Gia_ManSimulateWords( p, nSize[n] ); - - Vec_Bit_t * vBitX = Vec_BitAlloc( nSize[n] * Gia_ManCiNum(p) ); - Vec_Bit_t * vBitY = Vec_BitAlloc( nSize[n] * Gia_ManCoNum(p) ); - - FILE * pFileOutX = fopen( n ? pFileNameOutVX : pFileNameOutTX, "wb" ); - FILE * pFileOutY = fopen( n ? pFileNameOutVY : pFileNameOutTY, "wb" ); - - int i, k, Id, Num, Value, nBytes; - for ( k = 0; k < nSize[n]; k++ ) - { - Gia_ManForEachCiId( p, Id, i ) - { - Vec_BitPush( vBitX, Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); - //printf( "%d", Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); - } - //printf( " " ); - Gia_ManForEachCoId( p, Id, i ) - { - Vec_BitPush( vBitY, Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); - //printf( "%d", Abc_TtGetBit(Gia_ManObjSim(p, Id), k) ); - } - //printf( "\n" ); - } - assert( Vec_BitSize(vBitX) <= Vec_BitCap(vBitX) ); - assert( Vec_BitSize(vBitY) <= Vec_BitCap(vBitY) ); - - Num = 2; Value = fwrite( &Num, 1, 4, pFileOutX ); assert( Value == 4 ); - Num = nSize[n]; Value = fwrite( &Num, 1, 4, pFileOutX ); assert( Value == 4 ); - Num = Gia_ManCiNum(p); Value = fwrite( &Num, 1, 4, pFileOutX ); assert( Value == 4 ); - - nBytes = nSize[n] * Gia_ManCiNum(p) / 8; - assert( nSize[n] * Gia_ManCiNum(p) % 8 == 0 ); - Value = fwrite( Vec_BitArray(vBitX), 1, nBytes, pFileOutX ); - assert( Value == nBytes ); - - Num = 2; Value = fwrite( &Num, 1, 4, pFileOutY ); assert( Value == 4 ); - Num = nSize[n]; Value = fwrite( &Num, 1, 4, pFileOutY ); assert( Value == 4 ); - Num = Gia_ManCoNum(p); Value = fwrite( &Num, 1, 4, pFileOutY ); assert( Value == 4 ); - - nBytes = nSize[n] * Gia_ManCoNum(p) / 8; - assert( nSize[n] * Gia_ManCoNum(p) % 8 == 0 ); - Value = fwrite( Vec_BitArray(vBitY), 1, nBytes, pFileOutY ); - assert( Value == nBytes ); - - fclose( pFileOutX ); - fclose( pFileOutY ); - - Vec_BitFree( vBitX ); - Vec_BitFree( vBitY ); - - Res = 0; - } -} - -/**Function************************************************************* - Synopsis [] Description [] @@ -2449,6 +2290,7 @@ Gia_Man_t * Gia_ManDupWithMuxPos( Gia_Man_t * p ) return pNew; } + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/aig/gia/module.make b/src/aig/gia/module.make index 83179060..26909410 100644 --- a/src/aig/gia/module.make +++ b/src/aig/gia/module.make @@ -33,6 +33,7 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaFrames.c \ src/aig/gia/giaFront.c \ src/aig/gia/giaFx.c \ + src/aig/gia/giaGen.c \ src/aig/gia/giaGig.c \ src/aig/gia/giaGlitch.c \ src/aig/gia/giaHash.c \ @@ -75,6 +76,8 @@ SRC += src/aig/gia/giaAig.c \ src/aig/gia/giaSim.c \ src/aig/gia/giaSim2.c \ src/aig/gia/giaSim4.c \ + src/aig/gia/giaSim5.c \ + src/aig/gia/giaSimBase.c \ src/aig/gia/giaSort.c \ src/aig/gia/giaSpeedup.c \ src/aig/gia/giaSplit.c \ diff --git a/src/aig/miniaig/miniaig.h b/src/aig/miniaig/miniaig.h index 06769830..12061144 100644 --- a/src/aig/miniaig/miniaig.h +++ b/src/aig/miniaig/miniaig.h @@ -251,6 +251,64 @@ static int Mini_AigXor( Mini_Aig_t * p, int Lit0, int Lit1 ) return Mini_AigMux( p, Lit0, Mini_AigLitNot(Lit1), Lit1 ); } +static unsigned s_MiniTruths5[5] = { + 0xAAAAAAAA, + 0xCCCCCCCC, + 0xF0F0F0F0, + 0xFF00FF00, + 0xFFFF0000, +}; +static inline int Mini_AigTt5HasVar( unsigned t, int iVar ) +{ + return ((t << (1<<iVar)) & s_MiniTruths5[iVar]) != (t & s_MiniTruths5[iVar]); +} +static inline unsigned Mini_AigTt5Cofactor0( unsigned t, int iVar ) +{ + assert( iVar >= 0 && iVar < 6 ); + return (t & ~s_MiniTruths5[iVar]) | ((t & ~s_MiniTruths5[iVar]) << (1<<iVar)); +} +static inline unsigned Mini_AigTt5Cofactor1( unsigned t, int iVar ) +{ + assert( iVar >= 0 && iVar < 6 ); + return (t & s_MiniTruths5[iVar]) | ((t & s_MiniTruths5[iVar]) >> (1<<iVar)); +} +static inline int Mini_AigAndProp( Mini_Aig_t * p, int iLit0, int iLit1 ) +{ + if ( iLit0 < 2 ) + return iLit0 ? iLit1 : 0; + if ( iLit1 < 2 ) + return iLit1 ? iLit0 : 0; + if ( iLit0 == iLit1 ) + return iLit1; + if ( iLit0 == Mini_AigLitNot(iLit1) ) + return 0; + return Mini_AigAnd( p, iLit0, iLit1 ); +} +static inline int Mini_AigMuxProp( Mini_Aig_t * p, int iCtrl, int iData1, int iData0 ) +{ + int iTemp0 = Mini_AigAndProp( p, Mini_AigLitNot(iCtrl), iData0 ); + int iTemp1 = Mini_AigAndProp( p, iCtrl, iData1 ); + return Mini_AigLitNot( Mini_AigAndProp( p, Mini_AigLitNot(iTemp0), Mini_AigLitNot(iTemp1) ) ); +} +static inline int Mini_AigTruth( Mini_Aig_t * p, int * pVarLits, int nVars, unsigned Truth ) +{ + int Var, Lit0, Lit1; + if ( Truth == 0 ) + return 0; + if ( ~Truth == 0 ) + return 1; + assert( nVars > 0 ); + // find the topmost var + for ( Var = nVars-1; Var >= 0; Var-- ) + if ( Mini_AigTt5HasVar( Truth, Var ) ) + break; + assert( Var >= 0 ); + // cofactor + Lit0 = Mini_AigTruth( p, pVarLits, Var, Mini_AigTt5Cofactor0(Truth, Var) ); + Lit1 = Mini_AigTruth( p, pVarLits, Var, Mini_AigTt5Cofactor1(Truth, Var) ); + return Mini_AigMuxProp( p, pVarLits[Var], Lit1, Lit0 ); +} + // procedure to check the topological order during AIG construction static int Mini_AigCheck( Mini_Aig_t * p ) { diff --git a/src/aig/saig/saigInd.c b/src/aig/saig/saigInd.c index f437dba0..d3665c85 100644 --- a/src/aig/saig/saigInd.c +++ b/src/aig/saig/saigInd.c @@ -383,9 +383,9 @@ nextrun: else if ( status == l_Undef ) printf( "Conflict limit (%d) was reached during iteration %d.\n", nConfMax, f+1 ); else if ( fUnique || fUniqueAll ) - printf( "Completed %d interations and added %d uniqueness constraints.\n", f+1, nConstrs ); + printf( "Completed %d iterations and added %d uniqueness constraints.\n", f+1, nConstrs ); else - printf( "Completed %d interations.\n", f+1 ); + printf( "Completed %d iterations.\n", f+1 ); } // cleanup sat_solver_delete( pSat ); diff --git a/src/aig/saig/saigIsoFast.c b/src/aig/saig/saigIsoFast.c index 6378e4db..7393e7fc 100644 --- a/src/aig/saig/saigIsoFast.c +++ b/src/aig/saig/saigIsoFast.c @@ -236,7 +236,7 @@ Vec_Int_t * Iso_StoCollectInfo( Iso_Sto_t * p, Aig_Obj_t * pPo ) if ( fVerboseShow ) Vec_IntForEachEntry( vInfo, Entry, i ) { - Iso_Dat2_t Data = { Entry & 0xFFFF }; + Iso_Dat2_t Data = { (unsigned)Entry & 0xFFFF }; Iso_Dat_t * pData = (Iso_Dat_t *)&Data; printf( "%6d : ", i ); diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h index c35ba879..312354da 100644 --- a/src/base/abc/abc.h +++ b/src/base/abc/abc.h @@ -761,7 +761,7 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk ); extern ABC_DLL Abc_Ntk_t * Abc_NtkToNetlistBench( Abc_Ntk_t * pNtk ); /*=== abcNtbdd.c ==========================================================*/ extern ABC_DLL Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd, void * bFunc, char * pNamePo, Vec_Ptr_t * vNamesPi ); -extern ABC_DLL Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal ); +extern ABC_DLL Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal, int Limit ); extern ABC_DLL void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose ); extern ABC_DLL void * Abc_NtkFreeGlobalBdds( Abc_Ntk_t * pNtk, int fFreeMan ); extern ABC_DLL int Abc_NtkSizeOfGlobalBdds( Abc_Ntk_t * pNtk ); @@ -789,7 +789,7 @@ extern ABC_DLL void Abc_NtkMakeComb( Abc_Ntk_t * pNtk, int fRemove extern ABC_DLL void Abc_NtkPermute( Abc_Ntk_t * pNtk, int fInputs, int fOutputs, int fFlops, char * pFlopPermFile ); extern ABC_DLL void Abc_NtkUnpermute( Abc_Ntk_t * pNtk ); extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateFromSops( char * pName, Vec_Ptr_t * vSops ); -extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateFromGias( char * pName, Vec_Ptr_t * vGias ); +extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateFromGias( char * pName, Vec_Ptr_t * vGias, Gia_Man_t * pMulti ); /*=== abcObj.c ==========================================================*/ extern ABC_DLL Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type ); extern ABC_DLL void Abc_ObjRecycle( Abc_Obj_t * pObj ); diff --git a/src/base/abc/abcNtk.c b/src/base/abc/abcNtk.c index 8e10ab3b..7c54f3c4 100644 --- a/src/base/abc/abcNtk.c +++ b/src/base/abc/abcNtk.c @@ -2250,15 +2250,43 @@ Abc_Ntk_t * Abc_NtkCreateFromSops( char * pName, Vec_Ptr_t * vSops ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkCreateFromGias( char * pName, Vec_Ptr_t * vGias ) +Abc_Ntk_t * Abc_NtkCreateFromGias( char * pName, Vec_Ptr_t * vGias, Gia_Man_t * pMulti ) { - Gia_Man_t * pGia = (Gia_Man_t *)Vec_PtrEntry(vGias, 0); + Gia_Man_t * pGia = pMulti ? pMulti : (Gia_Man_t *)Vec_PtrEntry(vGias, 0); Abc_Ntk_t * pNtk = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 ); Abc_Obj_t * pAbcObj, * pAbcObjPo; Gia_Obj_t * pObj; int i, k; pNtk->pName = Extra_UtilStrsav( pName ); for ( k = 0; k < Gia_ManCiNum(pGia); k++ ) Abc_NtkCreatePi( pNtk ); + if ( pMulti ) + { + Gia_ManCleanValue(pGia); + Gia_ManForEachCi( pGia, pObj, k ) + pObj->Value = Abc_ObjId( Abc_NtkCi(pNtk, k) ); + Gia_ManForEachAnd( pGia, pObj, k ) + { + Abc_Obj_t * pAbcObj0 = Abc_NtkObj( pNtk, Gia_ObjFanin0(pObj)->Value ); + Abc_Obj_t * pAbcObj1 = Abc_NtkObj( pNtk, Gia_ObjFanin1(pObj)->Value ); + pAbcObj0 = Abc_ObjNotCond( pAbcObj0, Gia_ObjFaninC0(pObj) ); + pAbcObj1 = Abc_ObjNotCond( pAbcObj1, Gia_ObjFaninC1(pObj) ); + pAbcObj = Abc_AigAnd( (Abc_Aig_t *)pNtk->pManFunc, pAbcObj0, pAbcObj1 ); + pObj->Value = Abc_ObjId( pAbcObj ); + } + Gia_ManForEachCo( pGia, pObj, k ) + { + //pObj = Gia_ManCo(pGia, 0); + if ( Gia_ObjFaninId0p(pGia, pObj) == 0 ) + pAbcObj = Abc_ObjNot( Abc_AigConst1(pNtk) ); + else + pAbcObj = Abc_NtkObj( pNtk, Gia_ObjFanin0(pObj)->Value ); + pAbcObj = Abc_ObjNotCond( pAbcObj, Gia_ObjFaninC0(pObj) ); + pAbcObjPo = Abc_NtkCreatePo( pNtk ); + Abc_ObjAddFanin( pAbcObjPo, pAbcObj ); + } + } + else + { Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) { assert( Gia_ManCoNum(pGia) == 1 ); @@ -2283,6 +2311,7 @@ Abc_Ntk_t * Abc_NtkCreateFromGias( char * pName, Vec_Ptr_t * vGias ) pAbcObjPo = Abc_NtkCreatePo( pNtk ); Abc_ObjAddFanin( pAbcObjPo, pAbcObj ); } + } Abc_NtkAddDummyPiNames( pNtk ); Abc_NtkAddDummyPoNames( pNtk ); return pNtk; diff --git a/src/base/abc/abcUtil.c b/src/base/abc/abcUtil.c index 038079e8..1f0c9725 100644 --- a/src/base/abc/abcUtil.c +++ b/src/base/abc/abcUtil.c @@ -3141,10 +3141,10 @@ Vec_Wec_t * Abc_SopSynthesize( Vec_Ptr_t * vSops ) assert( Vec_WecSize(vRes) == iNode ); return vRes; } -Vec_Wec_t * Abc_GiaSynthesize( Vec_Ptr_t * vGias ) +Vec_Wec_t * Abc_GiaSynthesize( Vec_Ptr_t * vGias, Gia_Man_t * pMulti ) { Vec_Wec_t * vRes = NULL; - Abc_Ntk_t * pNtk = Abc_NtkCreateFromGias( "top", vGias ); + Abc_Ntk_t * pNtk = Abc_NtkCreateFromGias( "top", vGias, pMulti ); Abc_Ntk_t * pNtkNew; Abc_Obj_t * pObj, * pFanin; int i, k, iNode = 0; @@ -3173,7 +3173,7 @@ Gia_Man_t * Abc_GiaSynthesizeInter( Gia_Man_t * p ) Abc_Ntk_t * pNtkNew, * pNtk; Vec_Ptr_t * vGias = Vec_PtrAlloc( 1 ); Vec_PtrPush( vGias, p ); - pNtk = Abc_NtkCreateFromGias( "top", vGias ); + pNtk = Abc_NtkCreateFromGias( "top", vGias, NULL ); Vec_PtrFree( vGias ); Abc_FrameReplaceCurrentNetwork( Abc_FrameReadGlobalFrame(), pNtk ); Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), "balance; collapse; muxes; strash; dc2" ); diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 6a852bf7..85053e18 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -139,6 +139,7 @@ static int Abc_CommandTestTruth ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandRunEco ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandRunGen ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandRunSim ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandRunTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandRewrite ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -397,6 +398,7 @@ static int Abc_CommandAbc9PSig ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Status ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9MuxProfile ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9MuxPos ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9MuxStr ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9PrintTruth ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Unate ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Rex2Gia ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -411,9 +413,12 @@ static int Abc_CommandAbc9Trim ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Dfs ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Sim ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Sim3 ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9MLGen ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9MLTest ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9ReadSim ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9WriteSim ( Abc_Frame_t * pAbc, int argc, char ** argv ); -static int Abc_CommandAbc9SimPat ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9PrintSim ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9GenSim ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9SimRsb ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Resim ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9SpecI ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -516,6 +521,7 @@ static int Abc_CommandAbc9FFTest ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandAbc9Qbf ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9QVar ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9GenQbf ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandAbc9HomoQbf ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9SatFx ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9SatClp ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandAbc9Inse ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -853,6 +859,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Synthesis", "runeco", Abc_CommandRunEco, 0 ); Cmd_CommandAdd( pAbc, "Synthesis", "rungen", Abc_CommandRunGen, 0 ); Cmd_CommandAdd( pAbc, "Synthesis", "runsim", Abc_CommandRunSim, 0 ); + Cmd_CommandAdd( pAbc, "Synthesis", "runtest", Abc_CommandRunTest, 0 ); Cmd_CommandAdd( pAbc, "Synthesis", "rewrite", Abc_CommandRewrite, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "refactor", Abc_CommandRefactor, 1 ); @@ -1110,6 +1117,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&status", Abc_CommandAbc9Status, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&profile", Abc_CommandAbc9MuxProfile, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&muxpos", Abc_CommandAbc9MuxPos, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&muxstr", Abc_CommandAbc9MuxStr, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&print_truth", Abc_CommandAbc9PrintTruth, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&unate", Abc_CommandAbc9Unate, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&rex2gia", Abc_CommandAbc9Rex2Gia, 0 ); @@ -1124,9 +1132,12 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&dfs", Abc_CommandAbc9Dfs, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&sim", Abc_CommandAbc9Sim, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&sim3", Abc_CommandAbc9Sim3, 0 ); - Cmd_CommandAdd( pAbc, "ABC9", "&read_sim", Abc_CommandAbc9ReadSim, 0 ); - Cmd_CommandAdd( pAbc, "ABC9", "&write_sim", Abc_CommandAbc9WriteSim, 0 ); - Cmd_CommandAdd( pAbc, "ABC9", "&simpat", Abc_CommandAbc9SimPat, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&mlgen", Abc_CommandAbc9MLGen, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&mltest", Abc_CommandAbc9MLTest, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&sim_read", Abc_CommandAbc9ReadSim, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&sim_write", Abc_CommandAbc9WriteSim, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&sim_print", Abc_CommandAbc9PrintSim, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&sim_gen", Abc_CommandAbc9GenSim, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&simrsb", Abc_CommandAbc9SimRsb, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&resim", Abc_CommandAbc9Resim, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&speci", Abc_CommandAbc9SpecI, 0 ); @@ -1229,6 +1240,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "ABC9", "&qbf", Abc_CommandAbc9Qbf, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&qvar", Abc_CommandAbc9QVar, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&genqbf", Abc_CommandAbc9GenQbf, 0 ); + Cmd_CommandAdd( pAbc, "ABC9", "&homoqbf", Abc_CommandAbc9HomoQbf, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&satfx", Abc_CommandAbc9SatFx, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&satclp", Abc_CommandAbc9SatClp, 0 ); Cmd_CommandAdd( pAbc, "ABC9", "&inse", Abc_CommandAbc9Inse, 0 ); @@ -7039,20 +7051,26 @@ usage: ***********************************************************************/ int Abc_CommandRunEco( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fVerbose ); + extern void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fRandom, int fVerbose, int fVeryVerbose ); char * pFileNames[4] = {NULL}; - int c, fCheck = 0, fVerbose = 0; + int c, fCheck = 0, fRandom = 0, fVerbose = 0, fVeryVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "cvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "crvwh" ) ) != EOF ) { switch ( c ) { case 'c': fCheck ^= 1; break; + case 'r': + fRandom ^= 1; + break; case 'v': fVerbose ^= 1; break; + case 'w': + fVeryVerbose ^= 1; + break; case 'h': goto usage; default: @@ -7067,12 +7085,22 @@ int Abc_CommandRunEco( Abc_Frame_t * pAbc, int argc, char ** argv ) goto usage; } for ( c = 0; c < argc - globalUtilOptind; c++ ) + { + FILE * pFile = fopen( argv[globalUtilOptind+c], "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open input file \"%s\".\n", argv[globalUtilOptind+c] ); + return 0; + } + else + fclose( pFile ); pFileNames[c] = argv[globalUtilOptind+c]; - Acb_NtkRunEco( pFileNames, fCheck, fVerbose ); + } + Acb_NtkRunEco( pFileNames, fCheck, fRandom, fVerbose, fVeryVerbose ); return 0; usage: - Abc_Print( -2, "usage: runeco [-cvh] <implementation> <specification> <weights>\n" ); + Abc_Print( -2, "usage: runeco [-crvwh] <implementation> <specification> <weights>\n" ); Abc_Print( -2, "\t performs computation of patch functions during ECO,\n" ); Abc_Print( -2, "\t as described in the following paper: A. Q. Dao et al\n" ); Abc_Print( -2, "\t \"Efficient computation of ECO patch functions\", Proc. DAC\'18\n" ); @@ -7081,7 +7109,9 @@ usage: Abc_Print( -2, "\t http://cad-contest-2017.el.cycu.edu.tw/Problem_A/default.html as follows:\n" ); Abc_Print( -2, "\t \"runeco unit1/F.v unit1/G.v unit1/weight.txt; cec -n out.v unit1/G.v\")\n" ); Abc_Print( -2, "\t-c : toggle checking that the problem has a solution [default = %s]\n", fCheck? "yes": "no" ); + Abc_Print( -2, "\t-r : toggle using random permutation of support variables [default = %s]\n", fRandom? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing more verbose information [default = %s]\n", fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -7148,11 +7178,11 @@ usage: ***********************************************************************/ int Abc_CommandRunSim( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Acb_NtkRunSim( char * pFileName[4], int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fVerbose ); + extern void Acb_NtkRunSim( char * pFileName[4], int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fRandom, int fUseWeights, int fVerbose, int fVeryVerbose ); char * pFileNames[4] = {NULL, NULL, "out.v", NULL}; - int c, nWords = 4, nBeam = 4, LevL = 0, LevU = 0, fOrder = 0, fFancy = 0, fVerbose = 0; + int c, nWords = 8, nBeam = 4, LevL = -1, LevU = -1, fOrder = 0, fFancy = 0, fUseBuf = 0, fRandom = 0, fUseWeights = 0, fVerbose = 0, fVeryVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "WBLUofvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "WBLUofbruvwh" ) ) != EOF ) { switch ( c ) { @@ -7206,9 +7236,21 @@ int Abc_CommandRunSim( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'f': fFancy ^= 1; break; + case 'b': + fUseBuf ^= 1; + break; + case 'r': + fRandom ^= 1; + break; + case 'u': + fUseWeights ^= 1; + break; case 'v': fVerbose ^= 1; break; + case 'w': + fVeryVerbose ^= 1; + break; case 'h': goto usage; default: @@ -7223,11 +7265,22 @@ int Abc_CommandRunSim( Abc_Frame_t * pAbc, int argc, char ** argv ) Gia_ManRandom(1); for ( c = 0; c < argc - globalUtilOptind; c++ ) pFileNames[c] = argv[globalUtilOptind+c]; - Acb_NtkRunSim( pFileNames, nWords, nBeam, LevL, LevU, fOrder, fFancy, fVerbose ); + for ( c = 0; c < argc - globalUtilOptind - 1; c++ ) + { + FILE * pFile = fopen( pFileNames[c], "rb" ); + if ( pFile == NULL ) + { + printf( "Cannot open input file \"%s\".\n", pFileNames[c] ); + return 0; + } + else + fclose( pFile ); + } + Acb_NtkRunSim( pFileNames, nWords, nBeam, LevL, LevU, fOrder, fFancy, fUseBuf, fRandom, fUseWeights, fVerbose, fVeryVerbose ); return 0; usage: - Abc_Print( -2, "usage: runsim [-WBLU] [-ofvh] [-N <num>] <file1> <file2> <file3>\n" ); + Abc_Print( -2, "usage: runsim [-WBLU] [-ofbruvwh] [-N <num>] <file1> <file2> <file3>\n" ); Abc_Print( -2, "\t experimental simulation command\n" ); Abc_Print( -2, "\t-W <num> : the number of words of simulation info [default = %d]\n", nWords ); Abc_Print( -2, "\t-B <num> : the beam width parameter [default = %d]\n", nBeam ); @@ -7235,12 +7288,68 @@ usage: Abc_Print( -2, "\t-U <num> : the upper bound on level [default = %d]\n", LevU ); Abc_Print( -2, "\t-o : toggle using a different node ordering [default = %s]\n", fOrder? "yes": "no" ); Abc_Print( -2, "\t-f : toggle using experimental feature [default = %s]\n", fFancy? "yes": "no" ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-b : toggle using buffers [default = %s]\n", fUseBuf? "yes": "no" ); + Abc_Print( -2, "\t-r : toggle using random permutation of support variables [default = %s]\n", fRandom? "yes": "no" ); + Abc_Print( -2, "\t-u : toggle using topological info to select support variables [default = %s]\n", fUseWeights? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing more verbose information [default = %s]\n", fVeryVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandRunTest( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Acb_NtkRunTest( char * pFileNames[4], int fFancy, int fVerbose ); + char * pFileNames[4] = {NULL}; + int c, fFancy = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "fvh" ) ) != EOF ) + { + switch ( c ) + { + case 'f': + fFancy ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc - globalUtilOptind < 2 || argc - globalUtilOptind > 5 ) + { + Abc_Print( 1, "Expecting two or three file names on the command line.\n" ); + goto usage; + } + for ( c = 0; c < argc - globalUtilOptind; c++ ) + pFileNames[c] = argv[globalUtilOptind+c]; + Acb_NtkRunTest( pFileNames, fFancy, fVerbose ); + return 0; + +usage: + Abc_Print( -2, "usage: runtest [-fvh] <file1> <file2>\n" ); + Abc_Print( -2, "\t experimental simulation command\n" ); + Abc_Print( -2, "\t-f : toggle using experimental feature [default = %s]\n", fFancy? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* @@ -10927,15 +11036,25 @@ usage: int Abc_CommandMuxes( Abc_Frame_t * pAbc, int argc, char ** argv ) { Abc_Ntk_t * pNtk, * pNtkRes; - int c, fGlobal = 0; - + int c, fGlobal = 0, Limit = 1000000; pNtk = Abc_FrameReadNtk(pAbc); // set defaults Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "gh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "Bgh" ) ) != EOF ) { switch ( c ) { + case 'B': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-B\" should be followed by an integer.\n" ); + goto usage; + } + Limit = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Limit < 0 ) + goto usage; + break; case 'g': fGlobal ^= 1; break; @@ -10970,22 +11089,23 @@ int Abc_CommandMuxes( Abc_Frame_t * pAbc, int argc, char ** argv ) } // get the new network - pNtkRes = Abc_NtkBddToMuxes( pNtk, fGlobal ); + pNtkRes = Abc_NtkBddToMuxes( pNtk, fGlobal, Limit ); if ( pNtkRes == NULL ) { - Abc_Print( -1, "Converting to MUXes has failed.\n" ); - return 1; + Abc_Print( 0, "Converting to MUXes has failed.\n" ); + return 0; } // replace the current network Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); return 0; usage: - Abc_Print( -2, "usage: muxes [-gh]\n" ); - Abc_Print( -2, "\t converts the current network into a network derived by\n" ); - Abc_Print( -2, "\t replacing all nodes by DAGs isomorphic to the local BDDs\n" ); - Abc_Print( -2, "\t-g : toggle visualizing the global BDDs of primary outputs [default = %s].\n", fGlobal? "yes": "no" ); - Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "usage: muxes [-B num] [-gh]\n" ); + Abc_Print( -2, "\t converts the current network into a network derived by\n" ); + Abc_Print( -2, "\t replacing all nodes by DAGs isomorphic to the local BDDs\n" ); + Abc_Print( -2, "\t-B <num>: limit on live BDD nodes during collapsing [default = %d]\n", Limit ); + Abc_Print( -2, "\t-g : toggle visualizing the global BDDs of primary outputs [default = %s].\n", fGlobal? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -13559,6 +13679,7 @@ int Abc_CommandTestColor( Abc_Frame_t * pAbc, int argc, char ** argv ) ***********************************************************************/ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) { + extern void Gia_Gen2CodeTest(); extern void Dau_NetworkEnumTest(); //Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); int nCutMax = 1; @@ -13772,7 +13893,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) //Dau_NetworkEnumTest(); //Extra_SimulationTest( nDivMax, nNumOnes, fNewOrder ); //Mnist_ExperimentWithScaling( nDecMax ); - //Extra_ReadForestTest(); + Gia_Gen2CodeTest(); return 0; usage: Abc_Print( -2, "usage: test [-CKDNM] [-aovwh] <file_name>\n" ); @@ -23375,7 +23496,7 @@ int Abc_CommandSymFun( Abc_Frame_t * pAbc, int argc, char ** argv ) else printf( "Generated truth table of the %d-variable function (%s) and set it as the current network\n", nVars, pTruth ); } - else + else if ( nVars <= 8 ) printf( "%s\n", pTruth ); // read the truth table to be the current network in ABC pCommand = ABC_CALLOC( char, strlen(pTruth) + 100 ); @@ -30532,12 +30653,15 @@ usage: ***********************************************************************/ int Abc_CommandAbc9SaveAig( Abc_Frame_t * pAbc, int argc, char ** argv ) { - int c; + int c, fArea = 0; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "ah" ) ) != EOF ) { switch ( c ) { + case 'a': + fArea ^= 1; + break; case 'h': goto usage; default: @@ -30549,6 +30673,8 @@ int Abc_CommandAbc9SaveAig( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Empty network.\n" ); return 1; } + if ( fArea && pAbc->pGiaSaved != NULL && Gia_ManAndNum(pAbc->pGiaSaved) <= Gia_ManAndNum(pAbc->pGia) ) + return 0; // save the design as best Gia_ManStopP( &pAbc->pGiaSaved ); pAbc->pGiaSaved = Gia_ManDupWithAttributes( pAbc->pGia ); @@ -30557,6 +30683,7 @@ int Abc_CommandAbc9SaveAig( Abc_Frame_t * pAbc, int argc, char ** argv ) usage: Abc_Print( -2, "usage: &saveaig [-ah]\n" ); Abc_Print( -2, "\t saves the current AIG into the internal storage\n" ); + Abc_Print( -2, "\t-a : toggle saving AIG with the smaller area [default = %s]\n", fArea? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -31314,6 +31441,53 @@ usage: return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9MuxStr( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Gia_ManCofStructure( Gia_Man_t * p ); + Gia_Man_t * pGia; + int c, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9MuxStr(): There is no AIG.\n" ); + return 1; + } + pGia = Gia_ManCofStructure( pAbc->pGia ); + Abc_FrameUpdateGia( pAbc, pGia ); + return 0; + +usage: + Abc_Print( -2, "usage: &muxstr [-vh]\n" ); + Abc_Print( -2, "\t performs restructuring\n" ); + Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function************************************************************* @@ -31822,7 +31996,7 @@ int Abc_CommandAbc9Strash( Abc_Frame_t * pAbc, int argc, char ** argv ) } else if ( pAbc->pGia->pMuxes ) { - pTemp = Gia_ManDupNoMuxes( pAbc->pGia ); + pTemp = Gia_ManDupNoMuxes( pAbc->pGia, 0 ); if ( !Abc_FrameReadFlag("silentmode") ) printf( "Generated AIG from AND/XOR/MUX graph.\n" ); } @@ -32493,15 +32667,16 @@ usage: SeeAlso [] ***********************************************************************/ -int Abc_CommandAbc9ReadSim( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandAbc9MLGen( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Vec_Wrd_t * Gia_ManSimPatGenRandom( int nWords ); - extern Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName ); - int c, nWords = 4, fVerbose = 0; + extern void Gia_ManDumpFiles( Gia_Man_t * p, int nCexesT, int nCexesV, int Seed, char * pFileName ); + extern void Gia_ManDumpPlaFiles( Gia_Man_t * p, int nCexesT, int nCexesV, int Seed, char * pFileName ); + int c, Seed = 0, nWords = 10, fBinData = 0, fVerbose = 0; + char * pFileName = NULL; char ** pArgvNew; int nArgcNew; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Wvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "WSbvh" ) ) != EOF ) { switch ( c ) { @@ -32516,6 +32691,20 @@ int Abc_CommandAbc9ReadSim( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nWords < 0 ) goto usage; break; + case 'S': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-S\" should be followed by an integer.\n" ); + goto usage; + } + Seed = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( Seed < 0 ) + goto usage; + break; + case 'b': + fBinData ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -32527,44 +32716,213 @@ int Abc_CommandAbc9ReadSim( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pAbc->pGia == NULL ) { - Abc_Print( -1, "Abc_CommandAbc9ReadSim(): There is no AIG.\n" ); + Abc_Print( -1, "Abc_CommandAbc9MLGen(): There is no AIG.\n" ); return 1; } if ( Gia_ManRegNum(pAbc->pGia) > 0 ) { - Abc_Print( -1, "Abc_CommandAbc9ReadSim(): This command works only for combinational AIGs.\n" ); + Abc_Print( -1, "Abc_CommandAbc9MLGen(): This command works only for combinational AIGs.\n" ); return 0; } Vec_WrdFreeP( &pAbc->pGia->vSimsPi ); pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; if ( nArgcNew == 0 ) + printf( "Default file names will be used.\n" ); + else + pFileName = pArgvNew[0]; + if ( nArgcNew != 0 && nArgcNew != 1 ) + { + Abc_Print( -1, "File name is not given on the command line.\n" ); + return 1; + } + if ( fBinData ) + Gia_ManDumpFiles( pAbc->pGia, nWords, nWords, Seed, pFileName ); + else + Gia_ManDumpPlaFiles( pAbc->pGia, nWords, nWords, Seed, pFileName ); + return 0; + +usage: + Abc_Print( -2, "usage: &mlgen [-WS num] [-bvh] <file>\n" ); + Abc_Print( -2, "\t generates data files for machine learning\n" ); + Abc_Print( -2, "\t-W num : the number of words to simulate [default = %d]\n", nWords ); + Abc_Print( -2, "\t-S num : the random seed for simulation data (num < 10000) [default = %d]\n", Seed ); + Abc_Print( -2, "\t-b : toggle using binary data files [default = %s]\n", fBinData? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t<file> : file to store the simulation info\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9MLTest( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManTestOneFile( Gia_Man_t * p, char * pFileName, char * pDumpFile ); + int c, fVerbose = 0; + char * pDumpFile = NULL; + char ** pArgvNew; + int nArgcNew; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Dvh" ) ) != EOF ) + { + switch ( c ) + { + case 'D': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-D\" should be followed by a file name.\n" ); + goto usage; + } + pDumpFile = argv[globalUtilOptind]; + globalUtilOptind++; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9MLTest(): There is no AIG.\n" ); + return 1; + } + if ( Gia_ManRegNum(pAbc->pGia) > 0 ) + { + Abc_Print( -1, "Abc_CommandAbc9MLTest(): This command works only for combinational AIGs.\n" ); + return 0; + } + Vec_WrdFreeP( &pAbc->pGia->vSimsPi ); + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; + if ( nArgcNew != 1 ) + { + Abc_Print( -1, "Abc_CommandAbc9MLTest(): Expecting data file name on the command line.\n" ); + return 0; + } + Gia_ManTestOneFile( pAbc->pGia, pArgvNew[0], pDumpFile ); + return 0; + +usage: + Abc_Print( -2, "usage: &mltest [-vh] [-D file] <file>\n" ); + Abc_Print( -2, "\t testing command for machine learning data\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t-D file : file name to dump statistics [default = none]\n" ); + Abc_Print( -2, "\tfile : file with input simulation info\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9ReadSim( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Vec_Wrd_t * Gia_ManSimPatRead( char * pFileName ); + int c, fOutputs = 0, nWords = 4, fVerbose = 0; + char ** pArgvNew; + int nArgcNew; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Wovh" ) ) != EOF ) { - Gia_ManRandom( 1 ); - pAbc->pGia->vSimsPi = Gia_ManSimPatGenRandom( Gia_ManCiNum(pAbc->pGia) * nWords ); - printf( "Generated %d random patterns (%d 64-bit words) for each input of the AIG.\n", 64*nWords, nWords ); + switch ( c ) + { + case 'W': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" ); + goto usage; + } + nWords = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nWords < 0 ) + goto usage; + break; + case 'o': + fOutputs ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9ReadSim(): There is no AIG.\n" ); + return 1; + } + if ( Gia_ManRegNum(pAbc->pGia) > 0 ) + { + Abc_Print( -1, "Abc_CommandAbc9ReadSim(): This command works only for combinational AIGs.\n" ); return 0; } + pArgvNew = argv + globalUtilOptind; + nArgcNew = argc - globalUtilOptind; if ( nArgcNew != 1 ) { Abc_Print( -1, "File name is not given on the command line.\n" ); return 1; } - pAbc->pGia->vSimsPi = Gia_ManSimPatRead( pArgvNew[0] ); - if ( Vec_WrdSize(pAbc->pGia->vSimsPi) % Gia_ManCiNum(pAbc->pGia) != 0 ) + if ( fOutputs ) + { + Vec_WrdFreeP( &pAbc->pGia->vSimsPo ); + pAbc->pGia->vSimsPo = Gia_ManSimPatRead( pArgvNew[0] ); + if ( Vec_WrdSize(pAbc->pGia->vSimsPo) % Gia_ManCoNum(pAbc->pGia) != 0 ) + { + Vec_WrdFreeP( &pAbc->pGia->vSimsPo ); + Abc_Print( -1, "File size (%d words) does not match the number of AIG inputs (%d %% %d != %d).\n", + Vec_WrdSize(pAbc->pGia->vSimsPo), Vec_WrdSize(pAbc->pGia->vSimsPo), Gia_ManCiNum(pAbc->pGia), + Vec_WrdSize(pAbc->pGia->vSimsPo) % Gia_ManCiNum(pAbc->pGia) ); + return 1; + } + pAbc->pGia->nSimWords = Vec_WrdSize(pAbc->pGia->vSimsPo) / Gia_ManCoNum(pAbc->pGia); + } + else { Vec_WrdFreeP( &pAbc->pGia->vSimsPi ); - Abc_Print( -1, "File size (%d words) does not match the number of AIG inputs (%d %% %d = %d).\n", - Vec_WrdSize(pAbc->pGia->vSimsPi), Vec_WrdSize(pAbc->pGia->vSimsPi), Gia_ManCiNum(pAbc->pGia), - Vec_WrdSize(pAbc->pGia->vSimsPi) % Gia_ManCiNum(pAbc->pGia) ); - return 1; + pAbc->pGia->vSimsPi = Gia_ManSimPatRead( pArgvNew[0] ); + if ( Vec_WrdSize(pAbc->pGia->vSimsPi) % Gia_ManCiNum(pAbc->pGia) != 0 ) + { + Vec_WrdFreeP( &pAbc->pGia->vSimsPi ); + Abc_Print( -1, "File size (%d words) does not match the number of AIG inputs (%d %% %d != %d).\n", + Vec_WrdSize(pAbc->pGia->vSimsPi), Vec_WrdSize(pAbc->pGia->vSimsPi), Gia_ManCiNum(pAbc->pGia), + Vec_WrdSize(pAbc->pGia->vSimsPi) % Gia_ManCiNum(pAbc->pGia) ); + return 1; + } + pAbc->pGia->nSimWords = Vec_WrdSize(pAbc->pGia->vSimsPi) / Gia_ManCiNum(pAbc->pGia); } return 0; usage: - Abc_Print( -2, "usage: &read_sim [-W num] [-vh] <file>\n" ); + Abc_Print( -2, "usage: &sim_read [-W num] [-ovh] <file>\n" ); Abc_Print( -2, "\t reads simulation patterns from file\n" ); - Abc_Print( -2, "\t-W num : the number of frames to simulate [default = %d]\n", nWords ); + Abc_Print( -2, "\t-W num : the number of words to simulate [default = %d]\n", nWords ); + Abc_Print( -2, "\t-o : toggle reading output information [default = %s]\n", fOutputs? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t<file> : file to store the simulation info\n"); @@ -32585,14 +32943,17 @@ usage: int Abc_CommandAbc9WriteSim( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords ); - int c, fVerbose = 0; + int c, fOutputs = 0, fVerbose = 0; char ** pArgvNew; int nArgcNew; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ovh" ) ) != EOF ) { switch ( c ) { + case 'o': + fOutputs ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -32612,7 +32973,7 @@ int Abc_CommandAbc9WriteSim( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "Abc_CommandAbc9WriteSim(): This command works only for combinational AIGs.\n" ); return 0; } - if ( pAbc->pGia->vSimsPi == NULL ) + if ( (fOutputs ? pAbc->pGia->vSimsPo : pAbc->pGia->vSimsPi) == NULL ) { Abc_Print( -1, "Abc_CommandAbc9WriteSim(): Does not have simulation information available.\n" ); return 0; @@ -32624,13 +32985,22 @@ int Abc_CommandAbc9WriteSim( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( -1, "File name is not given on the command line.\n" ); return 1; } - assert( Vec_WrdSize(pAbc->pGia->vSimsPi) % Gia_ManCiNum(pAbc->pGia) == 0 ); - Gia_ManSimPatWrite( pArgvNew[0], pAbc->pGia->vSimsPi, Vec_WrdSize(pAbc->pGia->vSimsPi) / Gia_ManCiNum(pAbc->pGia) ); + if ( fOutputs ) + { + assert( Vec_WrdSize(pAbc->pGia->vSimsPo) % Gia_ManCoNum(pAbc->pGia) == 0 ); + Gia_ManSimPatWrite( pArgvNew[0], pAbc->pGia->vSimsPo, Vec_WrdSize(pAbc->pGia->vSimsPo) / Gia_ManCoNum(pAbc->pGia) ); + } + else + { + assert( Vec_WrdSize(pAbc->pGia->vSimsPi) % Gia_ManCiNum(pAbc->pGia) == 0 ); + Gia_ManSimPatWrite( pArgvNew[0], pAbc->pGia->vSimsPi, Vec_WrdSize(pAbc->pGia->vSimsPi) / Gia_ManCiNum(pAbc->pGia) ); + } return 0; usage: - Abc_Print( -2, "usage: &write_sim [-vh] <file>\n" ); + Abc_Print( -2, "usage: &sim_write [-vh] <file>\n" ); Abc_Print( -2, "\t writes simulation patterns into a file\n" ); + Abc_Print( -2, "\t-o : toggle writing output information [default = %s]\n", fOutputs? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); Abc_Print( -2, "\t<file> : file to store the simulation info\n"); @@ -32648,12 +33018,70 @@ usage: SeeAlso [] ***********************************************************************/ -int Abc_CommandAbc9SimPat( Abc_Frame_t * pAbc, int argc, char ** argv ) +int Abc_CommandAbc9PrintSim( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Gia_ManSimPat( Gia_Man_t * pGia, int nWords, int fVerbose ); - int c, nWords = 4, fVerbose = 0; + extern void Gia_ManSimProfile( Gia_Man_t * pGia ); + int c, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "Wvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + { + switch ( c ) + { + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pGia == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9PrintSim(): There is no AIG.\n" ); + return 1; + } + if ( Gia_ManRegNum(pAbc->pGia) > 0 ) + { + Abc_Print( -1, "Abc_CommandAbc9PrintSim(): This command works only for combinational AIGs.\n" ); + return 0; + } + if ( pAbc->pGia->vSimsPi == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9PrintSim(): Simulation patterns are not defined.\n" ); + return 0; + } + Gia_ManSimProfile( pAbc->pGia ); + return 0; + +usage: + Abc_Print( -2, "usage: &sim_print [-vh]\n" ); + Abc_Print( -2, "\t writes simulation patterns into a file\n" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandAbc9GenSim( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Gia_ManSimProfile( Gia_Man_t * pGia ); + extern void Gia_ManPatSatImprove( Gia_Man_t * pGia, int nWords, int fVerbose ); + extern void Gia_ManPatDistImprove( Gia_Man_t * p, int fVerbose ); + extern void Gia_ManPatRareImprove( Gia_Man_t * p, int RareLimit, int fVerbose ); + int c, nWords = 4, nRare = -1, fDist = 0, fSatBased = 0, fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "WRsdvh" ) ) != EOF ) { switch ( c ) { @@ -32668,6 +33096,23 @@ int Abc_CommandAbc9SimPat( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nWords < 0 ) goto usage; break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" ); + goto usage; + } + nRare = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nRare < 0 ) + goto usage; + break; + case 's': + fSatBased ^= 1; + break; + case 'd': + fDist ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -32679,27 +33124,59 @@ int Abc_CommandAbc9SimPat( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pAbc->pGia == NULL ) { - Abc_Print( -1, "Abc_CommandAbc9SimPat(): There is no AIG.\n" ); + Abc_Print( -1, "Abc_CommandAbc9GenSim(): There is no AIG.\n" ); return 1; } if ( Gia_ManRegNum(pAbc->pGia) > 0 ) { - Abc_Print( -1, "Abc_CommandAbc9SimPat(): This command works only for combinational AIGs.\n" ); + Abc_Print( -1, "Abc_CommandAbc9GenSim(): This command works only for combinational AIGs.\n" ); return 0; } - if ( pAbc->pGia->vSimsPi == NULL ) + if ( fSatBased ) { - Abc_Print( -1, "Abc_CommandAbc9SimPat(): Does not have simulation information available.\n" ); - return 0; + if ( pAbc->pGia->vSimsPi == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9GenSim(): Does not have simulation information available.\n" ); + return 0; + } + Gia_ManPatSatImprove( pAbc->pGia, nWords, fVerbose ); + } + else if ( fDist ) + { + if ( pAbc->pGia->vSimsPi == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9GenSim(): Does not have simulation information available.\n" ); + return 0; + } + Gia_ManPatDistImprove( pAbc->pGia, fVerbose ); } - Gia_ManSimPat( pAbc->pGia, nWords, fVerbose ); + else if ( nRare >= 0 ) + { + if ( pAbc->pGia->vSimsPi == NULL ) + { + Abc_Print( -1, "Abc_CommandAbc9GenSim(): Does not have simulation information available.\n" ); + return 0; + } + Gia_ManPatRareImprove( pAbc->pGia, nRare, fVerbose ); + } + else + { + Abc_Random(1); + Vec_WrdFreeP( &pAbc->pGia->vSimsPi ); + pAbc->pGia->vSimsPi = Vec_WrdStartRandom( Gia_ManCiNum(pAbc->pGia) * nWords ); + printf( "Generated %d random patterns (%d 64-bit data words) for each input of the AIG.\n", 64*nWords, nWords ); + } + Gia_ManSimProfile( pAbc->pGia ); return 0; usage: - Abc_Print( -2, "usage: &simpat [-W num] [-vh]\n" ); - Abc_Print( -2, "\t performs simulation of the AIG\n" ); - Abc_Print( -2, "\t-W num : the number of frames to simulate [default = %d]\n", nWords ); - Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "usage: &sim_gen [-WR num] [-sdvh]\n" ); + Abc_Print( -2, "\t generates random simulation patterns\n" ); + Abc_Print( -2, "\t-W num : the number of 64-bit words of simulation info [default = %d]\n", nWords ); + Abc_Print( -2, "\t-R num : the rarity parameter used to define scope [default = %d]\n", nRare ); + Abc_Print( -2, "\t-s : toggle using SAT-based improvement of available patterns [default = %s]\n", fSatBased? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle using one improvement of available patterns [default = %s]\n", fDist? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; } @@ -40191,13 +40668,14 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Dch( Abc_Frame_t * pAbc, int argc, char ** argv ) { + extern Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p ); Gia_Man_t * pTemp; Dch_Pars_t Pars, * pPars = &Pars; - int c, fEquiv = 0; + int c, fMinLevel = 0, fEquiv = 0; // set defaults Dch_ManSetDefaultParams( pPars ); Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "WCSsptfrevh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "WCSsptfremvh" ) ) != EOF ) { switch ( c ) { @@ -40252,6 +40730,9 @@ int Abc_CommandAbc9Dch( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'e': fEquiv ^= 1; break; + case 'm': + fMinLevel ^= 1; + break; case 'v': pPars->fVerbose ^= 1; break; @@ -40281,12 +40762,17 @@ int Abc_CommandAbc9Dch( Abc_Frame_t * pAbc, int argc, char ** argv ) pTemp = Gia_ManEquivReduce( pAbc->pGia, 1, 0, 0, 0 ); } else + { pTemp = Gia_ManPerformDch( pAbc->pGia, pPars ); + Abc_FrameUpdateGia( pAbc, pTemp ); + if ( fMinLevel ) + pTemp = Gia_ManEquivReduce2( pAbc->pGia ); + } Abc_FrameUpdateGia( pAbc, pTemp ); return 0; usage: - Abc_Print( -2, "usage: &dch [-WCS num] [-sptfrevh]\n" ); + Abc_Print( -2, "usage: &dch [-WCS num] [-sptfremvh]\n" ); Abc_Print( -2, "\t computes structural choices using a new approach\n" ); Abc_Print( -2, "\t-W num : the max number of simulation words [default = %d]\n", pPars->nWords ); Abc_Print( -2, "\t-C num : the max number of conflicts at a node [default = %d]\n", pPars->nBTLimit ); @@ -40297,6 +40783,7 @@ usage: Abc_Print( -2, "\t-f : toggle using lighter logic synthesis [default = %s]\n", pPars->fLightSynth? "yes": "no" ); Abc_Print( -2, "\t-r : toggle skipping choices with redundant support [default = %s]\n", pPars->fSkipRedSupp? "yes": "no" ); Abc_Print( -2, "\t-e : toggle computing and merging equivalences [default = %s]\n", fEquiv? "yes": "no" ); + Abc_Print( -2, "\t-m : toggle minimizing logic level after merging equivalences [default = %s]\n", fMinLevel? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", pPars->fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; @@ -43382,16 +43869,17 @@ usage: int Abc_CommandAbc9Qbf( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern void Gia_QbfDumpFile( Gia_Man_t * pGia, int nPars ); - extern int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, int nTimeOut, int fGlucose, int fVerbose ); + extern int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, int nTimeOut, int nEncVars, int fGlucose, int fVerbose ); int c, nPars = -1; int nIterLimit = 0; int nConfLimit = 0; int nTimeOut = 0; + int nEncVars = 0; int fDumpCnf = 0; int fGlucose = 0; int fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "PICTdgvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "PICTKdgvh" ) ) != EOF ) { switch ( c ) { @@ -43439,6 +43927,17 @@ int Abc_CommandAbc9Qbf( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( nTimeOut < 0 ) goto usage; break; + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + goto usage; + } + nEncVars = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nEncVars < 0 ) + goto usage; + break; case 'd': fDumpCnf ^= 1; break; @@ -43477,16 +43976,17 @@ int Abc_CommandAbc9Qbf( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( fDumpCnf ) Gia_QbfDumpFile( pAbc->pGia, nPars ); else - Gia_QbfSolve( pAbc->pGia, nPars, nIterLimit, nConfLimit, nTimeOut, fGlucose, fVerbose ); + Gia_QbfSolve( pAbc->pGia, nPars, nIterLimit, nConfLimit, nTimeOut, nEncVars, fGlucose, fVerbose ); return 0; usage: - Abc_Print( -2, "usage: &qbf [-PICT num] [-dgvh]\n" ); + Abc_Print( -2, "usage: &qbf [-PICTK num] [-dgvh]\n" ); Abc_Print( -2, "\t solves QBF problem EpVxM(p,x)\n" ); Abc_Print( -2, "\t-P num : number of parameters p (should be the first PIs) [default = %d]\n", nPars ); Abc_Print( -2, "\t-I num : quit after the given iteration even if unsolved [default = %d]\n", nIterLimit ); Abc_Print( -2, "\t-C num : conflict limit per problem [default = %d]\n", nConfLimit ); Abc_Print( -2, "\t-T num : global timeout [default = %d]\n", nTimeOut ); + Abc_Print( -2, "\t-K num : the number of input bits (for encoding miters only) [default = %d]\n", nEncVars ); Abc_Print( -2, "\t-d : toggle dumping QDIMACS file instead of solving [default = %s]\n", fDumpCnf? "yes": "no" ); Abc_Print( -2, "\t-g : toggle using Glucose 3.0 by Gilles Audemard and Laurent Simon [default = %s]\n", fGlucose? "yes": "no" ); Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); @@ -43705,6 +44205,75 @@ usage: SeeAlso [] ***********************************************************************/ +int Abc_CommandAbc9HomoQbf( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Gia_Gen2CreateMiter( int nLutSize, int nLutNum ); + int nLutSize = 2; + int nLutNum = 3; + int fVerbose = 0; + int c; + Gia_Man_t * pTemp; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "KNvh" ) ) != EOF ) + { + switch ( c ) + { + case 'K': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" ); + goto usage; + } + nLutSize = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLutSize < 0 ) + goto usage; + break; + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nLutNum = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nLutNum < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + pTemp = Gia_Gen2CreateMiter( nLutSize, nLutNum ); + Abc_FrameUpdateGia( pAbc, pTemp ); + return 0; + +usage: + Abc_Print( -2, "usage: &homoqbf [-KN num] [-vh]\n" ); + Abc_Print( -2, "\t generates QBF miter for the encoding problem\n" ); + Abc_Print( -2, "\t-K num : the LUT size [default = %d]\n", nLutSize ); + Abc_Print( -2, "\t-N num : the number of LUTs [default = %d]\n", nLutNum ); + Abc_Print( -2, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Abc_CommandAbc9SatFx( Abc_Frame_t * pAbc, int argc, char ** argv ) { extern int Bmc_FxCompute( Gia_Man_t * p ); @@ -47210,39 +47779,11 @@ usage: ***********************************************************************/ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) { - Gia_Man_t * pTemp = NULL; int c, fVerbose = 0; int nFrames = 5; int fSwitch = 0; int nWords = 1000; int nProcs = 2; -// extern Gia_Man_t * Gia_VtaTest( Gia_Man_t * p ); -// extern int Gia_ManSuppSizeTest( Gia_Man_t * p ); -// extern void Gia_VtaTest( Gia_Man_t * p, int nFramesStart, int nFramesMax, int nConfMax, int nTimeMax, int fVerbose ); -// extern void Gia_IsoTest( Gia_Man_t * p, int fVerbose ); -// extern void Ga2_ManComputeTest( Gia_Man_t * p ); -// extern void Bmc_CexTest( Gia_Man_t * p, Abc_Cex_t * pCex, int fVerbose ); -// extern void Gia_IsoTest( Gia_Man_t * p, Abc_Cex_t * pCex, int fVerbose ); -// extern void Unr_ManTest( Gia_Man_t * pGia, int nFrames ); -// extern int Gia_ManVerify( Gia_Man_t * pGia ); -// extern Gia_Man_t * Gia_ManOptimizeRing( Gia_Man_t * p ); -// extern void Gia_ManCollectSeqTest( Gia_Man_t * p ); -// extern Gia_Man_t * Gia_SweeperFraigTest( Gia_Man_t * p, int nWords, int nConfs, int fVerbose ); -// extern Gia_Man_t * Bmc_CexDepthTest( Gia_Man_t * p, Abc_Cex_t * pCex, int nFrames, int fVerbose ); -// extern Gia_Man_t * Bmc_CexTarget( Gia_Man_t * p, int nFrames ); -// extern void Gia_ManMuxProfiling( Gia_Man_t * p ); -// extern Gia_Man_t * Mig_ManTest( Gia_Man_t * pGia ); -// extern Gia_Man_t * Gia_ManInterTest( Gia_Man_t * p ); -// extern Gia_Man_t * Llb_ReachableStatesGia( Gia_Man_t * p ); -// extern Gia_Man_t * Unm_ManTest( Gia_Man_t * pGia ); -// extern void Agi_ManTest( Gia_Man_t * pGia ); -// extern void Gia_ManCheckFalseTest( Gia_Man_t * p, int nSlackMax ); -// extern void Gia_ParTest( Gia_Man_t * p, int nWords, int nProcs ); -// extern void Gia_ManTisTest( Gia_Man_t * pInit ); -// extern void Gia_StoComputeCuts( Gia_Man_t * p ); -// extern void Abc_BddGiaTest( Gia_Man_t * pGia, int fVerbose ); - extern Gia_Man_t * Dau_ConstructAigFromFile( char * pFileName ); - Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "WPFsvh" ) ) != EOF ) { @@ -47298,69 +47839,8 @@ int Abc_CommandAbc9Test( Abc_Frame_t * pAbc, int argc, char ** argv ) // Abc_Print( -1, "Abc_CommandAbc9Test(): There is no AIG.\n" ); // return 1; // } -/* - if ( pAbc->pCex == NULL ) - { - Abc_Print( -1, "Abc_CommandAbc9Test(): There is no CEX.\n" ); - return 1; - } -*/ -// Gia_ManFrontTest( pAbc->pGia ); -// Gia_ManReduceConst( pAbc->pGia, 1 ); -// Sat_ManTest( pAbc->pGia, Gia_ManCo(pAbc->pGia, 0), 0 ); -// Gia_ManTestDistance( pAbc->pGia ); -// Gia_SatSolveTest( pAbc->pGia ); -// For_ManExperiment( pAbc->pGia, 20, 1, 1 ); -// Gia_ManUnrollSpecial( pAbc->pGia, 5, 100, 1 ); -// pAbc->pGia = Gia_ManDupSelf( pTemp = pAbc->pGia ); -// pAbc->pGia = Gia_ManRemoveEnables( pTemp = pAbc->pGia ); -// Cbs_ManSolveTest( pAbc->pGia ); -// pAbc->pGia = Gia_VtaTest( pTemp = pAbc->pGia ); -// Gia_ManStopP( &pTemp ); -// Gia_ManSuppSizeTest( pAbc->pGia ); -// Gia_VtaTest( pAbc->pGia, 10, 100000, 0, 0, 1 ); -// Gia_IsoTest( pAbc->pGia, fVerbose ); -// Ga2_ManComputeTest( pAbc->pGia ); -// Bmc_CexTest( pAbc->pGia, pAbc->pCex, fVerbose ); -// Gia_IsoTest( pAbc->pGia, pAbc->pCex, 0 ); -// Unr_ManTest( pAbc->pGia, nFrames ); -// Gia_ManVerifyWithBoxes( pAbc->pGia ); -// Gia_ManCollectSeqTest( pAbc->pGia ); -// pTemp = Gia_ManOptimizeRing( pAbc->pGia ); -// pTemp = Gia_SweeperFraigTest( pAbc->pGia, 4, 1000, 0 ); -// Abc_FrameUpdateGia( pAbc, pTemp ); -// pTemp = Bmc_CexDepthTest( pAbc->pGia, pAbc->pCex, nFrames, fVerbose ); -// pTemp = Bmc_CexTarget( pAbc->pGia, nFrames ); -// Abc_FrameUpdateGia( pAbc, pTemp ); -// Gia_ManMuxProfiling( pAbc->pGia ); -// pTemp = Mig_ManTest( pAbc->pGia ); -// Abc_FrameUpdateGia( pAbc, pTemp ); -// pTemp = Gia_ManInterTest( pAbc->pGia ); -// Abc_FrameUpdateGia( pAbc, pTemp ); -// pTemp = Llb_ReachableStatesGia( pAbc->pGia ); -// Abc_FrameUpdateGia( pAbc, pTemp ); -// Unm_ManTest( pAbc->pGia ); -// Agi_ManTest( pAbc->pGia ); -// Gia_ManResubTest( pAbc->pGia ); -// Jf_ManTestCnf( pAbc->pGia ); -// Gia_ManCheckFalseTest( pAbc->pGia, nFrames ); -// Gia_ParTest( pAbc->pGia, nWords, nProcs ); -// Gia_StoComputeCuts( pAbc->pGia ); -// printf( "\nThis command is currently disabled.\n\n" ); -/* - { - char Buffer[10]; - extern void Gia_DumpLutSizeDistrib( Gia_Man_t * p, char * pFileName ); - sprintf( Buffer, "stats%d.txt", nFrames ); - if ( pAbc->pGia ) - Gia_DumpLutSizeDistrib( pAbc->pGia, Buffer ); - } -*/ -// pTemp = Slv_ManToAig( pAbc->pGia ); -// Abc_FrameUpdateGia( pAbc, pTemp ); -// Extra_TestGia2( pAbc->pGia ); - pTemp = Dau_ConstructAigFromFile( "lib4var2.txt" ); - Abc_FrameUpdateGia( pAbc, pTemp ); +// Abc_FrameUpdateGia( pAbc, Abc_Procedure(pAbc->pGia) ); +// Gia_SimQualityTest( pAbc->pGia ); return 0; usage: Abc_Print( -2, "usage: &test [-FW num] [-svh]\n" ); diff --git a/src/base/abci/abcNtbdd.c b/src/base/abci/abcNtbdd.c index 5dc662d7..d3a19d83 100644 --- a/src/base/abci/abcNtbdd.c +++ b/src/base/abci/abcNtbdd.c @@ -34,7 +34,7 @@ ABC_NAMESPACE_IMPL_START #ifdef ABC_USE_CUDD -static void Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); +static int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit ); static void Abc_NtkBddToMuxesPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ); static Abc_Obj_t * Abc_NodeBddToMuxes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew ); static Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * pNtkNew, st__table * tBdd2Node ); @@ -129,12 +129,18 @@ Abc_Ntk_t * Abc_NtkDeriveFromBdd( void * dd0, void * bFunc, char * pNamePo, Vec_ SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal ) +Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal, int Limit ) { Abc_Ntk_t * pNtkNew; pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP ); if ( fGlobal ) - Abc_NtkBddToMuxesPerformGlo( pNtk, pNtkNew ); + { + if ( !Abc_NtkBddToMuxesPerformGlo( pNtk, pNtkNew, Limit ) ) + { + Abc_NtkDelete( pNtkNew ); + return NULL; + } + } else { Abc_NtkBddToMuxesPerform( pNtk, pNtkNew ); @@ -259,17 +265,17 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t * SeeAlso [] ***********************************************************************/ -void Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) +int Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int Limit ) { DdManager * dd; Abc_Obj_t * pObj, * pObjNew; int i; st__table * tBdd2Node; assert( Abc_NtkIsStrash(pNtk) ); - dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, 0 ); + dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, Limit, 1, 1, 0, 0 ); if ( dd == NULL ) { printf( "Construction of global BDDs has failed.\n" ); - return; + return 0; } //printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) ); @@ -292,6 +298,7 @@ void Abc_NtkBddToMuxesPerformGlo( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew ) Abc_NtkFreeGlobalBdds( pNtk, 0 ); Extra_StopManager( dd ); Abc_NtkCleanCopy( pNtk ); + return 1; } /**Function************************************************************* @@ -655,7 +662,7 @@ ABC_PRT( "Time", Abc_Clock() - clk ); #else double Abc_NtkSpacePercentage( Abc_Obj_t * pNode ) { return 0.0; } -Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal ) { return NULL; } +Abc_Ntk_t * Abc_NtkBddToMuxes( Abc_Ntk_t * pNtk, int fGlobal, int Limit ) { return NULL; } #endif diff --git a/src/base/abci/abcQbf.c b/src/base/abci/abcQbf.c index aa67ad74..5ddd25f1 100644 --- a/src/base/abci/abcQbf.c +++ b/src/base/abci/abcQbf.c @@ -195,8 +195,6 @@ clkV = Abc_Clock() - clkV; ABC_PRT( "Syn", clkS ); // ABC_PRT( "Ver", clkV ); } - if ( nIters+1 == nItersMax ) - break; } Abc_NtkDelete( pNtkSyn ); // report the results @@ -206,12 +204,10 @@ clkV = Abc_Clock() - clkV; printf( "Parameters: " ); Abc_NtkVectorPrintPars( vPiValues, nPars ); printf( " Statistics: 0=%d 1=%d\n", nZeros, Vec_IntSize(vPiValues) - nZeros ); - printf( "Solved after %d interations. ", nIters ); + printf( "Solved after %d iterations. ", nIters ); } else if ( nIters == nItersMax ) - printf( "Unsolved after %d interations. ", nIters ); - else if ( nIters == nItersMax ) - printf( "Quit after %d interatios. ", nItersMax ); + printf( "Quit after %d iterations. ", nItersMax ); else printf( "Implementation does not exist. " ); ABC_PRT( "Total runtime", Abc_Clock() - clkTotal ); diff --git a/src/base/abci/abcResub.c b/src/base/abci/abcResub.c index 9323f9e7..b8934e23 100644 --- a/src/base/abci/abcResub.c +++ b/src/base/abci/abcResub.c @@ -650,14 +650,12 @@ Dec_Graph_t * Abc_ManResubQuit1( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t { Dec_Graph_t * pGraph; Dec_Edge_t eRoot, eNode0, eNode1; - assert( pObj0 != pObj1 ); - assert( !Abc_ObjIsComplement(pObj0) ); - assert( !Abc_ObjIsComplement(pObj1) ); + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj1) ); pGraph = Dec_GraphCreate( 2 ); - Dec_GraphNode( pGraph, 0 )->pFunc = pObj0; - Dec_GraphNode( pGraph, 1 )->pFunc = pObj1; - eNode0 = Dec_EdgeCreate( 0, pObj0->fPhase ); - eNode1 = Dec_EdgeCreate( 1, pObj1->fPhase ); + Dec_GraphNode( pGraph, 0 )->pFunc = Abc_ObjRegular(pObj0); + Dec_GraphNode( pGraph, 1 )->pFunc = Abc_ObjRegular(pObj1); + eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase ^ Abc_ObjIsComplement(pObj0) ); + eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ^ Abc_ObjIsComplement(pObj1) ); if ( fOrGate ) eRoot = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); else @@ -683,17 +681,16 @@ Dec_Graph_t * Abc_ManResubQuit21( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_ { Dec_Graph_t * pGraph; Dec_Edge_t eRoot, eNode0, eNode1, eNode2; - assert( pObj0 != pObj1 ); - assert( !Abc_ObjIsComplement(pObj0) ); - assert( !Abc_ObjIsComplement(pObj1) ); - assert( !Abc_ObjIsComplement(pObj2) ); + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj1) ); + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj2) ); + assert( Abc_ObjRegular(pObj1) != Abc_ObjRegular(pObj2) ); pGraph = Dec_GraphCreate( 3 ); - Dec_GraphNode( pGraph, 0 )->pFunc = pObj0; - Dec_GraphNode( pGraph, 1 )->pFunc = pObj1; - Dec_GraphNode( pGraph, 2 )->pFunc = pObj2; - eNode0 = Dec_EdgeCreate( 0, pObj0->fPhase ); - eNode1 = Dec_EdgeCreate( 1, pObj1->fPhase ); - eNode2 = Dec_EdgeCreate( 2, pObj2->fPhase ); + Dec_GraphNode( pGraph, 0 )->pFunc = Abc_ObjRegular(pObj0); + Dec_GraphNode( pGraph, 1 )->pFunc = Abc_ObjRegular(pObj1); + Dec_GraphNode( pGraph, 2 )->pFunc = Abc_ObjRegular(pObj2); + eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase ^ Abc_ObjIsComplement(pObj0) ); + eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ^ Abc_ObjIsComplement(pObj1) ); + eNode2 = Dec_EdgeCreate( 2, Abc_ObjRegular(pObj2)->fPhase ^ Abc_ObjIsComplement(pObj2) ); if ( fOrGate ) { eRoot = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); @@ -725,15 +722,14 @@ Dec_Graph_t * Abc_ManResubQuit2( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t { Dec_Graph_t * pGraph; Dec_Edge_t eRoot, ePrev, eNode0, eNode1, eNode2; - assert( pObj0 != pObj1 ); - assert( pObj0 != pObj2 ); - assert( pObj1 != pObj2 ); - assert( !Abc_ObjIsComplement(pObj0) ); + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj1) ); + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj2) ); + assert( Abc_ObjRegular(pObj1) != Abc_ObjRegular(pObj2) ); pGraph = Dec_GraphCreate( 3 ); Dec_GraphNode( pGraph, 0 )->pFunc = Abc_ObjRegular(pObj0); Dec_GraphNode( pGraph, 1 )->pFunc = Abc_ObjRegular(pObj1); Dec_GraphNode( pGraph, 2 )->pFunc = Abc_ObjRegular(pObj2); - eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase ); + eNode0 = Dec_EdgeCreate( 0, Abc_ObjRegular(pObj0)->fPhase ^ Abc_ObjIsComplement(pObj0) ); if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) { eNode1 = Dec_EdgeCreate( 1, Abc_ObjRegular(pObj1)->fPhase ); @@ -771,8 +767,8 @@ Dec_Graph_t * Abc_ManResubQuit3( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t { Dec_Graph_t * pGraph; Dec_Edge_t eRoot, ePrev0, ePrev1, eNode0, eNode1, eNode2, eNode3; - assert( pObj0 != pObj1 ); - assert( pObj2 != pObj3 ); + assert( Abc_ObjRegular(pObj0) != Abc_ObjRegular(pObj1) ); + assert( Abc_ObjRegular(pObj2) != Abc_ObjRegular(pObj3) ); pGraph = Dec_GraphCreate( 4 ); Dec_GraphNode( pGraph, 0 )->pFunc = Abc_ObjRegular(pObj0); Dec_GraphNode( pGraph, 1 )->pFunc = Abc_ObjRegular(pObj1); @@ -840,6 +836,7 @@ Dec_Graph_t * Abc_ManResubQuit3( Abc_Obj_t * pRoot, Abc_Obj_t * pObj0, Abc_Obj_t ***********************************************************************/ void Abc_ManResubDivsS( Abc_ManRes_t * p, int Required ) { + int fMoreDivs = 1; // bug fix by Siang-Yun Lee Abc_Obj_t * pObj; unsigned * puData, * puDataR; int i, w; @@ -863,6 +860,18 @@ void Abc_ManResubDivsS( Abc_ManRes_t * p, int Required ) Vec_PtrPush( p->vDivs1UP, pObj ); continue; } + if ( fMoreDivs ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( ~puData[w] & ~puDataR[w] ) + if ( ~puData[w] & ~puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs1UP, Abc_ObjNot(pObj) ); + continue; + } + } // check negative containment for ( w = 0; w < p->nWords; w++ ) // if ( ~puData[w] & puDataR[w] ) @@ -873,6 +882,18 @@ void Abc_ManResubDivsS( Abc_ManRes_t * p, int Required ) Vec_PtrPush( p->vDivs1UN, pObj ); continue; } + if ( fMoreDivs ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( puData[w] & puDataR[w] ) + if ( puData[w] & puDataR[w] & p->pCareSet[w] ) // care set + break; + if ( w == p->nWords ) + { + Vec_PtrPush( p->vDivs1UN, Abc_ObjNot(pObj) ); + continue; + } + } // add the node to binates Vec_PtrPush( p->vDivs1B, pObj ); } @@ -1081,14 +1102,38 @@ Dec_Graph_t * Abc_ManResubDivs1( Abc_ManRes_t * p, int Required ) // check positive unate divisors Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UP, pObj0, i ) { - puData0 = (unsigned *)pObj0->pData; + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UP, pObj1, k, i + 1 ) { - puData1 = (unsigned *)pObj1->pData; - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] | puData1[w]) != puDataR[w] ) - if ( ((puData0[w] | puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; + if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w]) != puDataR[w] ) + if ( ((~puData0[w] | ~puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w]) != puDataR[w] ) + if ( ((~puData0[w] | puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w]) != puDataR[w] ) + if ( ((puData0[w] | ~puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w]) != puDataR[w] ) + if ( ((puData0[w] | puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } if ( w == p->nWords ) { p->nUsedNode1Or++; @@ -1099,14 +1144,38 @@ Dec_Graph_t * Abc_ManResubDivs1( Abc_ManRes_t * p, int Required ) // check negative unate divisors Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UN, pObj0, i ) { - puData0 = (unsigned *)pObj0->pData; + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UN, pObj1, k, i + 1 ) { - puData1 = (unsigned *)pObj1->pData; - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] & puData1[w]) != puDataR[w] ) - if ( ((puData0[w] & puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; + if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w]) != puDataR[w] ) + if ( ((~puData0[w] & ~puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + if ( Abc_ObjIsComplement(pObj0) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w]) != puDataR[w] ) + if ( ((~puData0[w] & puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w]) != puDataR[w] ) + if ( ((puData0[w] & ~puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w]) != puDataR[w] ) + if ( ((puData0[w] & puData1[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } if ( w == p->nWords ) { p->nUsedNode1And++; @@ -1137,31 +1206,84 @@ Dec_Graph_t * Abc_ManResubDivs12( Abc_ManRes_t * p, int Required ) // check positive unate divisors Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UP, pObj0, i ) { - puData0 = (unsigned *)pObj0->pData; + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UP, pObj1, k, i + 1 ) { - puData1 = (unsigned *)pObj1->pData; + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UP, pObj2, j, k + 1 ) { - puData2 = (unsigned *)pObj2->pData; - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) - if ( ((puData0[w] | puData1[w] | puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; + puData2 = (unsigned *)Abc_ObjRegular(pObj2)->pData; + if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] | ~puData1[w] | ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] | ~puData1[w] | puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] | puData1[w] | ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] | puData1[w] | puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((puData0[w] | ~puData1[w] | ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((puData0[w] | ~puData1[w] | puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((puData0[w] | puData1[w] | ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | puData1[w] | puData2[w]) != puDataR[w] ) + if ( ((puData0[w] | puData1[w] | puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else assert( 0 ); if ( w == p->nWords ) { - LevelMax = Abc_MaxInt( pObj0->Level, Abc_MaxInt(pObj1->Level, pObj2->Level) ); + LevelMax = Abc_MaxInt( Abc_ObjRegular(pObj0)->Level, Abc_MaxInt(Abc_ObjRegular(pObj1)->Level, Abc_ObjRegular(pObj2)->Level) ); assert( LevelMax <= Required - 1 ); pObjMax = NULL; - if ( (int)pObj0->Level == LevelMax ) + if ( (int)Abc_ObjRegular(pObj0)->Level == LevelMax ) pObjMax = pObj0, pObjMin0 = pObj1, pObjMin1 = pObj2; - if ( (int)pObj1->Level == LevelMax ) + if ( (int)Abc_ObjRegular(pObj1)->Level == LevelMax ) { if ( pObjMax ) continue; pObjMax = pObj1, pObjMin0 = pObj0, pObjMin1 = pObj2; } - if ( (int)pObj2->Level == LevelMax ) + if ( (int)Abc_ObjRegular(pObj2)->Level == LevelMax ) { if ( pObjMax ) continue; pObjMax = pObj2, pObjMin0 = pObj0, pObjMin1 = pObj1; @@ -1178,31 +1300,84 @@ Dec_Graph_t * Abc_ManResubDivs12( Abc_ManRes_t * p, int Required ) // check negative unate divisors Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UN, pObj0, i ) { - puData0 = (unsigned *)pObj0->pData; + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UN, pObj1, k, i + 1 ) { - puData1 = (unsigned *)pObj1->pData; + puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; Vec_PtrForEachEntryStart( Abc_Obj_t *, p->vDivs1UN, pObj2, j, k + 1 ) { - puData2 = (unsigned *)pObj2->pData; - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) - if ( ((puData0[w] & puData1[w] & puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; + puData2 = (unsigned *)Abc_ObjRegular(pObj2)->pData; + if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] & ~puData1[w] & ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] & ~puData1[w] & puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] & puData1[w] & ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((~puData0[w] & puData1[w] & puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((puData0[w] & ~puData1[w] & ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((puData0[w] & ~puData1[w] & puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((puData0[w] & puData1[w] & ~puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( !Abc_ObjIsComplement(pObj0) && !Abc_ObjIsComplement(pObj1) && !Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & puData1[w] & puData2[w]) != puDataR[w] ) + if ( ((puData0[w] & puData1[w] & puData2[w]) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else assert( 0 ); if ( w == p->nWords ) { - LevelMax = Abc_MaxInt( pObj0->Level, Abc_MaxInt(pObj1->Level, pObj2->Level) ); + LevelMax = Abc_MaxInt( Abc_ObjRegular(pObj0)->Level, Abc_MaxInt(Abc_ObjRegular(pObj1)->Level, Abc_ObjRegular(pObj2)->Level) ); assert( LevelMax <= Required - 1 ); pObjMax = NULL; - if ( (int)pObj0->Level == LevelMax ) + if ( (int)Abc_ObjRegular(pObj0)->Level == LevelMax ) pObjMax = pObj0, pObjMin0 = pObj1, pObjMin1 = pObj2; - if ( (int)pObj1->Level == LevelMax ) + if ( (int)Abc_ObjRegular(pObj1)->Level == LevelMax ) { if ( pObjMax ) continue; pObjMax = pObj1, pObjMin0 = pObj0, pObjMin1 = pObj2; } - if ( (int)pObj2->Level == LevelMax ) + if ( (int)Abc_ObjRegular(pObj2)->Level == LevelMax ) { if ( pObjMax ) continue; pObjMax = pObj2, pObjMin0 = pObj0, pObjMin1 = pObj1; @@ -1239,40 +1414,74 @@ Dec_Graph_t * Abc_ManResubDivs2( Abc_ManRes_t * p, int Required ) // check positive unate divisors Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UP, pObj0, i ) { - puData0 = (unsigned *)pObj0->pData; + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs2UP0, pObj1, k ) { pObj2 = (Abc_Obj_t *)Vec_PtrEntry( p->vDivs2UP1, k ); puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; puData2 = (unsigned *)Abc_ObjRegular(pObj2)->pData; - if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) - { - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] | (puData1[w] | puData2[w])) != puDataR[w] ) - if ( ((puData0[w] | (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; - } - else if ( Abc_ObjIsComplement(pObj1) ) + if ( Abc_ObjIsComplement(pObj0) ) { - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] | (~puData1[w] & puData2[w])) != puDataR[w] ) - if ( ((puData0[w] | (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; - } - else if ( Abc_ObjIsComplement(pObj2) ) - { - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] | (puData1[w] & ~puData2[w])) != puDataR[w] ) - if ( ((puData0[w] | (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; + if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] | puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] | (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (~puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] | (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] & ~puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] | (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] | (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } } - else + else { - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] | (puData1[w] & puData2[w])) != puDataR[w] ) - if ( ((puData0[w] | (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; + if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] | puData2[w])) != puDataR[w] ) + if ( ((puData0[w] | (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (~puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((puData0[w] | (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] & ~puData2[w])) != puDataR[w] ) + if ( ((puData0[w] | (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] | (puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((puData0[w] | (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } } if ( w == p->nWords ) { @@ -1284,40 +1493,74 @@ Dec_Graph_t * Abc_ManResubDivs2( Abc_ManRes_t * p, int Required ) // check negative unate divisors Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs1UN, pObj0, i ) { - puData0 = (unsigned *)pObj0->pData; + puData0 = (unsigned *)Abc_ObjRegular(pObj0)->pData; Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs2UN0, pObj1, k ) { pObj2 = (Abc_Obj_t *)Vec_PtrEntry( p->vDivs2UN1, k ); puData1 = (unsigned *)Abc_ObjRegular(pObj1)->pData; puData2 = (unsigned *)Abc_ObjRegular(pObj2)->pData; - if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) - { - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] & (puData1[w] | puData2[w])) != puDataR[w] ) - if ( ((puData0[w] & (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; - } - else if ( Abc_ObjIsComplement(pObj1) ) + if ( Abc_ObjIsComplement(pObj0) ) { - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] & (~puData1[w] & puData2[w])) != puDataR[w] ) - if ( ((puData0[w] & (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; - } - else if ( Abc_ObjIsComplement(pObj2) ) - { - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] & (puData1[w] & ~puData2[w])) != puDataR[w] ) - if ( ((puData0[w] & (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; + if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] | puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] & (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (~puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] & (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] & ~puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] & (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((~puData0[w] & (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } } - else + else { - for ( w = 0; w < p->nWords; w++ ) -// if ( (puData0[w] & (puData1[w] & puData2[w])) != puDataR[w] ) - if ( ((puData0[w] & (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set - break; + if ( Abc_ObjIsComplement(pObj1) && Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] | puData2[w])) != puDataR[w] ) + if ( ((puData0[w] & (puData1[w] | puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj1) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (~puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((puData0[w] & (~puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else if ( Abc_ObjIsComplement(pObj2) ) + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] & ~puData2[w])) != puDataR[w] ) + if ( ((puData0[w] & (puData1[w] & ~puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } + else + { + for ( w = 0; w < p->nWords; w++ ) + // if ( (puData0[w] & (puData1[w] & puData2[w])) != puDataR[w] ) + if ( ((puData0[w] & (puData1[w] & puData2[w])) ^ puDataR[w]) & p->pCareSet[w] ) // care set + break; + } } if ( w == p->nWords ) { @@ -1472,6 +1715,7 @@ Dec_Graph_t * Abc_ManResubDivs3( Abc_ManRes_t * p, int Required ) } } } + /* // check negative unate divisors Vec_PtrForEachEntry( Abc_Obj_t *, p->vDivs2UN0, pObj0, i ) @@ -1493,85 +1737,85 @@ Dec_Graph_t * Abc_ManResubDivs3( Abc_ManRes_t * p, int Required ) { case 0: // 0000 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] & puData1[w]) & (puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & puData1[w]) & (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 1: // 0001 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] & puData1[w]) & (puData2[w] & ~puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & puData1[w]) & (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 2: // 0010 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] & puData1[w]) & (~puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & puData1[w]) & (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 3: // 0011 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] & puData1[w]) & (puData2[w] | puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & puData1[w]) & (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 4: // 0100 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] & ~puData1[w]) & (puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & ~puData1[w]) & (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 5: // 0101 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] & ~puData1[w]) & (puData2[w] & ~puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & ~puData1[w]) & (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 6: // 0110 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] & ~puData1[w]) & (~puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & ~puData1[w]) & (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 7: // 0111 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] & ~puData1[w]) & (puData2[w] | puData3[w])) != puDataR[w] ) + if ( (((puData0[w] & ~puData1[w]) & (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 8: // 1000 for ( w = 0; w < p->nWords; w++ ) - if ( ((~puData0[w] & puData1[w]) & (puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((~puData0[w] & puData1[w]) & (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 9: // 1001 for ( w = 0; w < p->nWords; w++ ) - if ( ((~puData0[w] & puData1[w]) & (puData2[w] & ~puData3[w])) != puDataR[w] ) + if ( (((~puData0[w] & puData1[w]) & (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 10: // 1010 for ( w = 0; w < p->nWords; w++ ) - if ( ((~puData0[w] & puData1[w]) & (~puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((~puData0[w] & puData1[w]) & (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 11: // 1011 for ( w = 0; w < p->nWords; w++ ) - if ( ((~puData0[w] & puData1[w]) & (puData2[w] | puData3[w])) != puDataR[w] ) + if ( (((~puData0[w] & puData1[w]) & (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 12: // 1100 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] | puData1[w]) & (puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] | puData1[w]) & (puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 13: // 1101 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] | puData1[w]) & (puData2[w] & ~puData3[w])) != puDataR[w] ) + if ( (((puData0[w] | puData1[w]) & (puData2[w] & ~puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 14: // 1110 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] | puData1[w]) & (~puData2[w] & puData3[w])) != puDataR[w] ) + if ( (((puData0[w] | puData1[w]) & (~puData2[w] & puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; case 15: // 1111 for ( w = 0; w < p->nWords; w++ ) - if ( ((puData0[w] | puData1[w]) & (puData2[w] | puData3[w])) != puDataR[w] ) + if ( (((puData0[w] | puData1[w]) & (puData2[w] | puData3[w])) ^ puDataR[w]) & p->pCareSet[w] ) break; break; diff --git a/src/base/acb/acb.h b/src/base/acb/acb.h index 36300efd..9aed414c 100644 --- a/src/base/acb/acb.h +++ b/src/base/acb/acb.h @@ -1028,6 +1028,8 @@ extern void Acb_NtkPrintNode( Acb_Ntk_t * p, int iObj ); extern int Acb_NtkCreateNode( Acb_Ntk_t * p, word uTruth, Vec_Int_t * vSupp ); extern void Acb_NtkUpdateNode( Acb_Ntk_t * p, int Pivot, word uTruth, Vec_Int_t * vSupp ); +extern Acb_Ntk_t * Acb_VerilogSimpleRead( char * pFileName, char * pFileNameW ); + ABC_NAMESPACE_HEADER_END diff --git a/src/base/acb/acbAbc.c b/src/base/acb/acbAbc.c index 9c2db080..cea89809 100644 --- a/src/base/acb/acbAbc.c +++ b/src/base/acb/acbAbc.c @@ -167,6 +167,7 @@ Acb_Ntk_t * Acb_NtkFromNdr( char * pFileName, void * pModule, Abc_Nam_t * pNames Acb_Man_t * pMan = Acb_ManAlloc( pFileName, 1, Abc_NamRef(pNames), NULL, NULL, NULL ); int k, NameId = Abc_NamStrFindOrAdd( pMan->pStrs, pMan->pName, NULL ); int Mod = 2, Obj, Type, nArray, * pArray, ObjId; + int Token0 = Abc_NamStrFind( pMan->pStrs, "1\'b0" ); Acb_Ntk_t * pNtk = Acb_NtkAlloc( pMan, NameId, Ndr_DataCiNum(p, Mod), Ndr_DataCoNum(p, Mod), Ndr_DataObjNum(p, Mod) ); Vec_Int_t * vMap = Vec_IntStart( nNameIdMax ); Acb_NtkCleanObjWeights( pNtk ); @@ -198,20 +199,30 @@ Acb_Ntk_t * Acb_NtkFromNdr( char * pFileName, void * pModule, Abc_Nam_t * pNames } Ndr_ModForEachNode( p, Mod, Obj ) { - //char * pName; - NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT ); - //pName = Abc_NamStr( pMan->pStrs, NameId ); + int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT ); + char * pName = Abc_NamStr( pMan->pStrs, NameId ); ObjId = Vec_IntEntry( vMap, NameId ); nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray ); for ( k = 0; k < nArray; k++ ) + { + if ( Vec_IntEntry(vMap, pArray[k]) == 0 ) + printf( "Cannot find fanin %d of node \"%s\".\n", k, pName ); Acb_ObjAddFanin( pNtk, ObjId, Vec_IntEntry(vMap, pArray[k]) ); + } Acb_ObjSetWeight( pNtk, ObjId, vWeights ? Vec_IntEntry(vWeights, NameId) : 1 ); } Ndr_ModForEachPo( p, Mod, Obj ) { + int NameId = Ndr_ObjReadBody( p, Obj, NDR_OUTPUT ); + char * pName = Abc_NamStr( pMan->pStrs, NameId ); nArray = Ndr_ObjReadArray( p, Obj, NDR_INPUT, &pArray ); assert( nArray == 1 ); ObjId = Acb_ObjAlloc( pNtk, ABC_OPER_CO, 1, 0 ); + if ( Vec_IntEntry(vMap, pArray[0]) == 0 ) + { + printf( "Adding constant 0 driver to non-driven PO \"%s\".\n", pName ); + Vec_IntWriteEntry( vMap, pArray[0], Token0 ); + } Acb_ObjAddFanin( pNtk, ObjId, Vec_IntEntry(vMap, pArray[0]) ); Acb_ObjSetName( pNtk, ObjId, pArray[0] ); } diff --git a/src/base/acb/acbFunc.c b/src/base/acb/acbFunc.c index 6ffeb0e8..8f72a00f 100644 --- a/src/base/acb/acbFunc.c +++ b/src/base/acb/acbFunc.c @@ -26,6 +26,8 @@ #include "map/mio/mio.h" #include "misc/util/utilTruth.h" #include "aig/gia/giaAig.h" +#include "base/main/main.h" +#include "base/cmd/cmd.h" ABC_NAMESPACE_IMPL_START @@ -187,15 +189,30 @@ Vec_Int_t * Acb_VerilogSimpleLex( char * pFileName, Abc_Nam_t * pNames ) { Vec_Int_t * vBuffer = Vec_IntAlloc( 1000 ); char * pBuffer = Extra_FileReadContents( pFileName ); - char * pToken; + char * pToken, * pStart, * pLimit = pBuffer + strlen(pBuffer); if ( pBuffer == NULL ) return NULL; Acb_VerilogRemoveComments( pBuffer ); - pToken = strtok( pBuffer, " \n\r\t()," ); + pToken = strtok( pBuffer, " \n\r\t(),;=" ); while ( pToken ) { - Vec_IntPush( vBuffer, Abc_NamStrFindOrAdd(pNames, pToken, NULL) ); - pToken = strtok( NULL, " \n\r\t(),;" ); + int iToken = Abc_NamStrFindOrAdd( pNames, pToken, NULL ); + if ( !strcmp(pToken, "assign") ) + Vec_IntPush( vBuffer, ACB_BUF ); + else + Vec_IntPush( vBuffer, iToken ); + if ( iToken >= ACB_BUF && iToken < ACB_UNUSED ) + { + for ( pStart = pToken; pStart < pLimit && *pStart != '\n'; pStart++ ) + if ( *pStart == '(' ) + break; + if ( *pStart == '(' ) + { + pToken = strtok( pStart, " \n\r\t(),;=" ); + continue; + } + } + pToken = strtok( NULL, " \n\r\t(),;=" ); } ABC_FREE( pBuffer ); return vBuffer; @@ -230,12 +247,12 @@ void * Acb_VerilogSimpleParse( Vec_Int_t * vBuffer, Abc_Nam_t * pNames ) vCur = vWires; else if ( Token >= ACB_BUF && Token <= ACB_XNOR ) { - char * pToken = Abc_NamStr(pNames, Vec_IntEntry(vBuffer, i+1)); + //char * pToken = Abc_NamStr(pNames, Vec_IntEntry(vBuffer, i+1)); Vec_IntPush( vTypes, Token ); Vec_IntPush( vTypes, Vec_IntSize(vFanins) ); vCur = vFanins; - if ( pToken[1] == 'z' && pToken[2] == '_' && pToken[3] == 'g' && pToken[4] == '_' ) - i++; + //if ( pToken[1] == 'z' && pToken[2] == '_' && pToken[3] == 'g' && pToken[4] == '_' ) + // i++; } else Vec_IntPush( vCur, Token ); @@ -243,7 +260,7 @@ void * Acb_VerilogSimpleParse( Vec_Int_t * vBuffer, Abc_Nam_t * pNames ) Vec_IntPush( vTypes, -1 ); Vec_IntPush( vTypes, Vec_IntSize(vFanins) ); // create design - pDesign = Ndr_Create( Vec_IntEntry(vBuffer, 1) ); + pDesign = (Ndr_Data_t *)Ndr_Create( Vec_IntEntry(vBuffer, 1) ); ModuleID = Ndr_AddModule( pDesign, Vec_IntEntry(vBuffer, 1) ); // create inputs Ndr_DataResize( pDesign, Vec_IntSize(vInputs) ); @@ -480,6 +497,9 @@ Vec_Int_t * Acb_NtkFindRoots( Acb_Ntk_t * p, Vec_Int_t * vTargets, Vec_Bit_t ** Acb_NtkIncTravId( p ); Acb_NtkForEachCi( p, iObj, i ) Acb_ObjSetTravIdCur( p, iObj ); + // visit internal nodes + Acb_NtkForEachNode( p, iObj ) + Acb_NtkFindRoots_rec(p, iObj, vBlock); // collect outputs reachable from targets Acb_NtkForEachCoDriver( p, iObj, i ) if ( Acb_NtkFindRoots_rec(p, iObj, vBlock) ) @@ -562,7 +582,7 @@ Vec_Int_t * Acb_NtkFindDivsCis( Acb_Ntk_t * p, Vec_Int_t * vSupp ) Vec_Int_t * Acb_NtkFindDivs( Acb_Ntk_t * p, Vec_Int_t * vSupp, Vec_Bit_t * vBlock, int fVerbose ) { int fPrintWeights = 0; - int nDivLimit = 3000; + int nDivLimit = 5000; int i, iObj; Vec_Int_t * vDivs = Vec_IntAlloc( 1000 ); // mark inputs @@ -726,7 +746,7 @@ Gia_Man_t * Acb_NtkToGia( Acb_Ntk_t * p, Vec_Int_t * vSupp, Vec_Int_t * vNodes, Acb_NtkForEachCoDriverVec( vRoots, p, iObj, i ) Gia_ManAppendCo( pNew, Acb_ObjCopy(p, iObj) ); // add divisor as primary outputs (if the divisors are not primary inputs) - if ( vDivs && Vec_IntSize(vDivs) > Vec_IntSize(vSupp) ) + if ( vDivs )//&& Vec_IntSize(vDivs) > Vec_IntSize(vSupp) ) Vec_IntForEachEntry( vDivs, iObj, i ) Gia_ManAppendCo( pNew, Acb_ObjCopy(p, iObj) ); Gia_ManHashStop( pNew ); @@ -791,7 +811,7 @@ Gia_Man_t * Acb_CreateMiter( Gia_Man_t * pF, Gia_Man_t * pG ) SeeAlso [] ***********************************************************************/ -#define NWORDS 64 +#define NWORDS 256 void Vec_IntPermute( Vec_Int_t * p ) { @@ -889,11 +909,16 @@ Vec_Int_t * Acb_FindSupportStart( sat_solver * pSat, int iFirstDiv, Vec_Int_t * fFound = 1; } if ( fFound == 0 ) + break; +/* + if ( fFound == 0 ) { + printf( "For some reason, cannot find a divisor.\n" ); Vec_WrdFree( vPats ); Vec_IntFree( vSupp ); return NULL; } +*/ assert( fFound ); iPat++; } @@ -983,6 +1008,7 @@ Vec_Int_t * Acb_FindSupportNext( sat_solver * pSat, int iFirstDiv, Vec_Int_t * v (*pnPats)++; if ( *pnPats == NWORDS*64 ) { + printf( "Exceeded %d words.\n", NWORDS ); Vec_IntFreeP( &vSupp ); return NULL; } @@ -1085,7 +1111,7 @@ Vec_Int_t * Acb_FindSupport( sat_solver * pSat, int iFirstDiv, Vec_Int_t * vWeig abctime clkLimit = TimeOut * CLOCKS_PER_SEC + Abc_Clock(); Vec_Wrd_t * vPats = NULL; int nPats = 0; - Vec_Int_t * vSuppBest, * vSupp;//, * vTemp; + Vec_Int_t * vSuppBest, * vSupp, * vTemp; int CostBest, Cost; int Iter; @@ -1094,26 +1120,22 @@ Vec_Int_t * Acb_FindSupport( sat_solver * pSat, int iFirstDiv, Vec_Int_t * vWeig vSuppBest = Vec_IntDup( vSuppStart ); printf( "Starting cost = %d.\n", CostBest ); - // interatively find the one with the most ones in the uncovered rows - for ( Iter = 0; Iter < 200; Iter++ ) + // iteratively find the one with the most ones in the uncovered rows + for ( Iter = 0; Iter < 500; Iter++ ) { if ( Abc_Clock() > clkLimit ) { - Vec_IntFree( vSuppBest ); - Vec_WrdFree( vPats ); - return NULL; + printf( "Timeout after %d sec.\n", TimeOut ); + break; } if ( Iter == 0 ) vSupp = Acb_FindSupportStart( pSat, iFirstDiv, vWeights, &vPats, &nPats ); else vSupp = Acb_FindSupportNext( pSat, iFirstDiv, vWeights, vPats, &nPats ); if ( vSupp == NULL ) - { - Vec_IntFree( vSuppBest ); - return NULL; - } - //vSupp = Acb_FindSupportMin( pSat, iFirstDiv, vPats, &nPats, vTemp = vSupp ); - //Vec_IntFree( vTemp ); + break; + vSupp = Acb_FindSupportMin( pSat, iFirstDiv, vPats, &nPats, vTemp = vSupp ); + Vec_IntFree( vTemp ); if ( vSupp == NULL ) break; Cost = Acb_ComputeSuppCost( vSupp, vWeights, iFirstDiv ); @@ -1122,15 +1144,15 @@ Vec_Int_t * Acb_FindSupport( sat_solver * pSat, int iFirstDiv, Vec_Int_t * vWeig { CostBest = Cost; ABC_SWAP( Vec_Int_t *, vSuppBest, vSupp ); - printf( "Iter %4d: Next cost = %d. ", Iter, Cost ); + printf( "Iter %4d: Next cost = %5d. ", Iter, Cost ); printf( "Updating best solution.\n" ); } Vec_IntFree( vSupp ); } - Acb_FindReplace( pSat, iFirstDiv, vWeights, vPats, nPats, vSuppBest ); - + if ( vPats ) + Acb_FindReplace( pSat, iFirstDiv, vWeights, vPats, nPats, vSuppBest ); //printf( "Number of patterns = %d.\n", nPats ); - Vec_WrdFree( vPats ); + Vec_WrdFreeP( &vPats ); return vSuppBest; } @@ -1878,13 +1900,31 @@ Vec_Ptr_t * Acb_GenerateSignalNames( Acb_Ntk_t * p, Vec_Int_t * vDivs, Vec_Int_t Vec_Str_t * Acb_GeneratePatch( Acb_Ntk_t * p, Vec_Int_t * vDivs, Vec_Int_t * vUsed, Vec_Ptr_t * vSops, Vec_Ptr_t * vGias, Vec_Int_t * vTars ) { extern Vec_Wec_t * Abc_SopSynthesize( Vec_Ptr_t * vSops ); - extern Vec_Wec_t * Abc_GiaSynthesize( Vec_Ptr_t * vGias ); - Vec_Wec_t * vGates = vGias ? Abc_GiaSynthesize(vGias) : Abc_SopSynthesize(vSops); Vec_Int_t * vGate; + extern Vec_Wec_t * Abc_GiaSynthesize( Vec_Ptr_t * vGias, Gia_Man_t * pMulti ); + Vec_Wec_t * vGates = vGias ? Abc_GiaSynthesize(vGias, NULL) : Abc_SopSynthesize(vSops); Vec_Int_t * vGate; int nOuts = vGias ? Vec_PtrSize(vGias) : Vec_PtrSize(vSops); int i, k, iObj, nWires = Vec_WecSize(vGates) - Vec_IntSize(vUsed) - nOuts, fFirst = 1; Vec_Ptr_t * vNames = Acb_GenerateSignalNames( p, vDivs, vUsed, nWires, vTars, vGates ); - Vec_Str_t * vStr = Vec_StrAlloc( 100 ); + + int nInvs = 0, nBufs = 0, nNodes = 0, nConst = 0; + Vec_WecForEachLevelStartStop( vGates, vGate, i, Vec_IntSize(vUsed), Vec_IntSize(vUsed)+nWires ) + { + if ( Vec_IntSize(vGate) > 2 ) + { + char * pName = Acb_Oper2Name(Vec_IntEntry(vGate, 0)); + if ( !strcmp(pName, "buf") ) + nBufs++; + else if ( !strcmp(pName, "not") ) + nInvs++; + else + nNodes++; + } + else + nConst++; + } + Vec_StrPrintF( vStr, "// Patch statistics: in = %d out = %d gate = %d (const = %d buf = %d inv = %d other = %d)\n\n", + Vec_IntSize(vUsed), nOuts, nWires, nConst, nBufs, nInvs, nNodes ); Vec_StrAppend( vStr, "module patch (" ); assert( Vec_IntSize(vTars) == nOuts ); @@ -1940,9 +1980,146 @@ Vec_Str_t * Acb_GeneratePatch( Acb_Ntk_t * p, Vec_Int_t * vDivs, Vec_Int_t * vUs Vec_PtrFreeFree( vNames ); Vec_WecFree( vGates ); - printf( "Synthesized patch with %d inputs, %d outputs and %d gates.\n", Vec_IntSize(vUsed), nOuts, nWires ); + printf( "Synthesized patch with %d inputs, %d outputs and %d gates (const = %d buf = %d inv = %d other = %d).\n", + Vec_IntSize(vUsed), nOuts, nWires, nConst, nBufs, nInvs, nNodes ); + return vStr; +} + +/**Function************************************************************* + + Synopsis [Patch generation.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Str_t * Acb_GenerateInstance2( Vec_Ptr_t * vIns, Vec_Ptr_t * vOuts ) +{ + char * pName; int i; + Vec_Str_t * vStr = Vec_StrAlloc( 100 ); + Vec_StrAppend( vStr, " patch p0 (" ); + Vec_PtrForEachEntry( char *, vOuts, pName, i ) + Vec_StrPrintF( vStr, "%s .%s(t%d_%s)", i ? ",":"", pName, i, pName ); + Vec_PtrForEachEntry( char *, vIns, pName, i ) + Vec_StrPrintF( vStr, ", .%s(%s)", pName, pName ); + Vec_StrAppend( vStr, " );\n\n" ); + Vec_StrPush( vStr, '\0' ); + return vStr; +} +Vec_Ptr_t * Acb_GenerateSignalNames2( Vec_Wec_t * vGates, Vec_Ptr_t * vIns, Vec_Ptr_t * vOuts ) +{ + int nIns = Vec_PtrSize(vIns), nOuts = Vec_PtrSize(vOuts); + int nNodes = Vec_WecSize(vGates) - nIns - nOuts; + Vec_Ptr_t * vRes = Vec_PtrStart( Vec_WecSize(vGates) ); char * pName; + Vec_Str_t * vStr = Vec_StrAlloc(1000); int i, nWires = 1; + // create input names + Vec_PtrForEachEntry( char *, vIns, pName, i ) + Vec_PtrWriteEntry( vRes, i, Abc_UtilStrsav(pName) ); + // create names for nodes driving outputs + Vec_PtrForEachEntry( char *, vOuts, pName, i ) + { + Vec_Int_t * vGate = Vec_WecEntry( vGates, nIns + nNodes + i ); + assert( Vec_IntEntry(vGate, 0) == ABC_OPER_BIT_BUF ); + Vec_PtrWriteEntry( vRes, Vec_IntEntry(vGate, 1), Abc_UtilStrsav(pName) ); + } + for ( i = nIns; i < nIns + nNodes; i++ ) + if ( Vec_PtrEntry(vRes, i) == NULL ) + { + Vec_StrPrintF( vStr, "ww%d", nWires++ ); + Vec_StrPush( vStr, '\0' ); + Vec_PtrWriteEntry( vRes, i, Vec_StrReleaseArray(vStr) ); + } + Vec_StrFree( vStr ); + return vRes; +} +Vec_Str_t * Acb_GeneratePatch2( Gia_Man_t * pGia, Vec_Ptr_t * vIns, Vec_Ptr_t * vOuts ) +{ + extern Vec_Wec_t * Abc_GiaSynthesize( Vec_Ptr_t * vGias, Gia_Man_t * pMulti ); + Vec_Wec_t * vGates = Abc_GiaSynthesize( NULL, pGia ); Vec_Int_t * vGate; + int nIns = Vec_PtrSize(vIns), nOuts = Vec_PtrSize(vOuts); char * pName; + int i, k, iObj, nWires = Vec_WecSize(vGates) - nIns - nOuts, fFirst = 1; + Vec_Ptr_t * vNames = Acb_GenerateSignalNames2( vGates, vIns, vOuts ); + + Vec_Str_t * vStr = Vec_StrAlloc( 100 ); + Vec_StrAppend( vStr, "module patch (" ); + + Vec_PtrForEachEntry( char *, vOuts, pName, i ) + Vec_StrPrintF( vStr, "%s %s", i ? ",":"", pName ); + Vec_PtrForEachEntry( char *, vIns, pName, i ) + Vec_StrPrintF( vStr, ", %s", pName ); + Vec_StrAppend( vStr, " );\n\n" ); + + Vec_StrAppend( vStr, " output" ); + Vec_PtrForEachEntry( char *, vOuts, pName, i ) + Vec_StrPrintF( vStr, "%s %s", i ? ",":"", pName ); + Vec_StrAppend( vStr, ";\n" ); + + Vec_StrAppend( vStr, " input" ); + Vec_PtrForEachEntry( char *, vIns, pName, i ) + Vec_StrPrintF( vStr, "%s %s", i ? ",":"", pName ); + Vec_StrAppend( vStr, ";\n" ); + + if ( nWires > nOuts ) + { + Vec_StrAppend( vStr, " wire" ); + for ( i = 0; i < nWires; i++ ) + { + char * pName = (char *)Vec_PtrEntry( vNames, nIns+i ); + if ( !strncmp(pName, "ww", 2) ) + Vec_StrPrintF( vStr, "%s %s", fFirst ? "":",", pName ), fFirst = 0; + } + Vec_StrAppend( vStr, ";\n\n" ); + } + + // create internal nodes + Vec_WecForEachLevelStartStop( vGates, vGate, i, nIns, nIns+nWires ) + { + if ( Vec_IntSize(vGate) > 2 ) + { + Vec_StrPrintF( vStr, " %s (", Acb_Oper2Name(Vec_IntEntry(vGate, 0)) ); + Vec_IntForEachEntryStart( vGate, iObj, k, 1 ) + Vec_StrPrintF( vStr, "%s %s", k > 1 ? ",":"", (char *)Vec_PtrEntry(vNames, iObj) ); + Vec_StrAppend( vStr, " );\n" ); + } + else + { + assert( Vec_IntEntry(vGate, 0) == ABC_OPER_CONST_F || Vec_IntEntry(vGate, 0) == ABC_OPER_CONST_T ); + Vec_StrPrintF( vStr, " %s (", Acb_Oper2Name( ABC_OPER_BIT_BUF ) ); + Vec_StrPrintF( vStr, " %s, ", (char *)Vec_PtrEntry(vNames, Vec_IntEntry(vGate, 1)) ); + Vec_StrPrintF( vStr, " 1\'b%d", Vec_IntEntry(vGate, 0) == ABC_OPER_CONST_T ); + Vec_StrPrintF( vStr, " );\n" ); + } + } + Vec_StrAppend( vStr, "\nendmodule\n\n" ); + Vec_StrPush( vStr, '\0' ); + Vec_PtrFreeFree( vNames ); + Vec_WecFree( vGates ); + + printf( "Synthesized patch with %d inputs, %d outputs and %d gates.\n", nIns, nOuts, nWires ); return vStr; } +void Acb_GenerateFile2( Gia_Man_t * pGia, Vec_Ptr_t * vIns, Vec_Ptr_t * vOuts, char * pFileName, char * pFileNameOut ) +{ + extern void Acb_GenerateFilePatch( Vec_Str_t * p, char * pFileNamePatch ); + extern void Acb_GenerateFileOut( Vec_Str_t * vPatchLine, char * pFileNameF, char * pFileNameOut, Vec_Str_t * vPatch ); + extern void Acb_NtkInsert( char * pFileNameIn, char * pFileNameOut, Vec_Ptr_t * vNames, int fNumber ); + Vec_Str_t * vInst = Acb_GenerateInstance2( vIns, vOuts ); + Vec_Str_t * vPatch = Acb_GeneratePatch2( pGia, vIns, vOuts ); + //printf( "%s", Vec_StrArray(vPatch) ); + //Gia_AigerWrite( pGia, "test.aig", 0, 0, 0 ); + // generate output files + Acb_GenerateFilePatch( vPatch, "patch.v" ); + printf( "Finished dumping patch file \"%s\".\n", "patch.v" ); + Acb_NtkInsert( pFileName, "temp.v", vOuts, 0 ); + printf( "Finished dumping intermediate file \"%s\".\n", "temp.v" ); + Acb_GenerateFileOut( vInst, "temp.v", pFileNameOut, vPatch ); + printf( "Finished dumping the resulting file \"%s\".\n", pFileNameOut ); + Vec_StrFree( vInst ); + Vec_StrFree( vPatch ); +} /**Function************************************************************* @@ -2328,7 +2505,7 @@ Vec_Ptr_t * Acb_TransformPatchFunctions( Vec_Ptr_t * vSops, Vec_Wec_t * vSupps, SeeAlso [] ***********************************************************************/ -int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4], int fCisOnly, int fCheck, int fVerbose ) +int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4], int fCisOnly, int fCheck, int fVerbose, int fVeryVerbose ) { extern Gia_Man_t * Abc_SopSynthesizeOne( char * pSop, int fClp ); @@ -2364,7 +2541,7 @@ int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4] Vec_Str_t * vInst = NULL, * vPatch = NULL; char * pSop = NULL; - int i, Res; + int i; if ( fVerbose ) { @@ -2458,6 +2635,8 @@ int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4] // add to functions Vec_PtrPush( vSops, pSop ); + if ( fVeryVerbose ) + printf( "Function %d\n%s", i, pSop ); } // add to supports Vec_IntAppend( Vec_WecPushLevel(vSupps), vSupp ); @@ -2468,6 +2647,7 @@ int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4] printf( "\n" ); if ( !fCisOnly ) { + int Res; abctime clk = Abc_Clock(); pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pGiaM, 8, 0, 0, 0, 0 ); Res = Acb_CheckMiter( pCnf ); @@ -2501,7 +2681,7 @@ int Acb_NtkEcoPerform( Acb_Ntk_t * pNtkF, Acb_Ntk_t * pNtkG, char * pFileName[4] // generate output files if ( pFileName[3] == NULL ) Acb_GenerateFilePatch( vPatch, "patch.v" ); - Acb_GenerateFileOut( vInst, pFileName[0], pFileName[3] ? pFileName[3] : "out.v", vPatch ); + Acb_GenerateFileOut( vInst, pFileName[0], pFileName[3] ? pFileName[3] : (char *)"out.v", vPatch ); printf( "Finished dumping resulting file \"%s\".\n\n", pFileName[3] ? pFileName[3] : "out.v" ); //Gia_AigerWrite( pGiaG, "test.aig", 0, 0, 0 ); cleanup: @@ -2557,7 +2737,6 @@ void Acb_NtkTestRun2( char * pFileNames[3], int fVerbose ) Acb_IntallLibrary(); } - /**Function************************************************************* Synopsis [Top level procedure.] @@ -2569,8 +2748,9 @@ void Acb_NtkTestRun2( char * pFileNames[3], int fVerbose ) SeeAlso [] ***********************************************************************/ -void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fVerbose ) +void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fRandom, int fVerbose, int fVeryVerbose ) { + char Command[1000]; int Result = 1; Acb_Ntk_t * pNtkF = Acb_VerilogSimpleRead( pFileNames[0], pFileNames[2] ); Acb_Ntk_t * pNtkG = Acb_VerilogSimpleRead( pFileNames[1], NULL ); if ( !pNtkF || !pNtkG ) @@ -2578,23 +2758,36 @@ void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fVerbose ) //int * pArray = Vec_IntArray( &pNtkF->vTargets ); //ABC_SWAP( int, pArray[7], pArray[4] ); //Vec_IntReverseOrder( &pNtkF->vTargets ); - //Vec_IntPermute( &pNtkF->vTargets ); - //Vec_IntPrint( &pNtkF->vTargets ); + if ( fRandom ) + { + printf( "Permuting targets as follows: " ); + Vec_IntPermute( &pNtkF->vTargets ); + Vec_IntPrint( &pNtkF->vTargets ); + } assert( Acb_NtkCiNum(pNtkF) == Acb_NtkCiNum(pNtkG) ); assert( Acb_NtkCoNum(pNtkF) == Acb_NtkCoNum(pNtkG) ); Acb_IntallLibrary(); - if ( !Acb_NtkEcoPerform( pNtkF, pNtkG, pFileNames, 0, fCheck, fVerbose ) ) + if ( !Acb_NtkEcoPerform( pNtkF, pNtkG, pFileNames, 0, fCheck, fVerbose, fVeryVerbose ) ) { - printf( "General computation timed out. Trying inputs only.\n\n" ); - if ( !Acb_NtkEcoPerform( pNtkF, pNtkG, pFileNames, 1, fCheck, fVerbose ) ) - printf( "Input-only computation also timed out.\n\n" ); +// printf( "General computation timed out. Trying inputs only.\n\n" ); +// if ( !Acb_NtkEcoPerform( pNtkF, pNtkG, pFileNames, 1, fCheck, fVerbose, fVeryVerbose ) ) +// printf( "Input-only computation also timed out.\n\n" ); + printf( "Computation did not succeed.\n" ); + Result = 0; } Acb_ManFree( pNtkF->pDesign ); Acb_ManFree( pNtkG->pDesign ); + + // verify the result + sprintf( Command, "read %s; strash; write temp1.aig; read %s; strash; write temp2.aig; &cec temp1.aig temp2.aig", + pFileNames[1], pFileNames[3] ? pFileNames[3] : "out.v" ); + if ( Result && Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command ) ) + fprintf( stdout, "Cannot execute command \"%s\".\n", Command ); + printf( "\n" ); } //////////////////////////////////////////////////////////////////////// diff --git a/src/base/acb/acbTest.c b/src/base/acb/acbTest.c new file mode 100644 index 00000000..fa632ca0 --- /dev/null +++ b/src/base/acb/acbTest.c @@ -0,0 +1,55 @@ +/**CFile**************************************************************** + + FileName [acbTest.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Hierarchical word-level netlist.] + + Synopsis [] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - July 21, 2015.] + + Revision [$Id: acbTest.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "acb.h" + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acb_NtkRunTest( char * pFileNames[4], int fFancy, int fVerbose ) +{ +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/acb/acbUtil.c b/src/base/acb/acbUtil.c index 001a137b..2243541b 100644 --- a/src/base/acb/acbUtil.c +++ b/src/base/acb/acbUtil.c @@ -20,6 +20,7 @@ #include "acb.h" #include "base/abc/abc.h" +#include "base/io/ioAbc.h" ABC_NAMESPACE_IMPL_START @@ -27,6 +28,7 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// @@ -502,7 +504,7 @@ Vec_Int_t * Acb_NtkFindNodes2( Acb_Ntk_t * p ) Acb_NtkFindNodes2_rec( p, Acb_ObjFanin(p, iObj, 0), vNodes ); return vNodes; } -int Acb_ObjToGia2( Gia_Man_t * pNew, Acb_Ntk_t * p, int iObj, Vec_Int_t * vTemp ) +int Acb_ObjToGia2( Gia_Man_t * pNew, int fUseBuf, Acb_Ntk_t * p, int iObj, Vec_Int_t * vTemp, int fUseXors ) { //char * pName = Abc_NamStr( p->pDesign->pStrs, Acb_ObjName(p, iObj) ); int * pFanin, iFanin, k, Type, Res; @@ -518,10 +520,11 @@ int Acb_ObjToGia2( Gia_Man_t * pNew, Acb_Ntk_t * p, int iObj, Vec_Int_t * vTemp return 0; if ( Type == ABC_OPER_CONST_T ) return 1; - if ( Type == ABC_OPER_BIT_BUF ) - return Vec_IntEntry(vTemp, 0); - if ( Type == ABC_OPER_BIT_INV ) - return Abc_LitNot( Vec_IntEntry(vTemp, 0) ); + if ( Type == ABC_OPER_BIT_BUF || Type == ABC_OPER_BIT_INV ) + { + Res = fUseBuf ? Gia_ManAppendBuf(pNew, Vec_IntEntry(vTemp, 0)) : Vec_IntEntry(vTemp, 0); + return Abc_LitNotCond( Res, Type == ABC_OPER_BIT_INV ); + } if ( Type == ABC_OPER_BIT_AND || Type == ABC_OPER_BIT_NAND ) { Res = 1; @@ -540,13 +543,13 @@ int Acb_ObjToGia2( Gia_Man_t * pNew, Acb_Ntk_t * p, int iObj, Vec_Int_t * vTemp { Res = 0; Vec_IntForEachEntry( vTemp, iFanin, k ) - Res = Gia_ManAppendXor2( pNew, Res, iFanin ); + Res = fUseXors ? Gia_ManAppendXorReal2(pNew, Res, iFanin) : Gia_ManAppendXor2(pNew, Res, iFanin); return Abc_LitNotCond( Res, Type == ABC_OPER_BIT_NXOR ); } assert( 0 ); return -1; } -Gia_Man_t * Acb_NtkToGia2( Acb_Ntk_t * p ) +Gia_Man_t * Acb_NtkToGia2( Acb_Ntk_t * p, int fUseBuf, int fUseXors, Vec_Int_t * vTargets, int nTargets ) { Gia_Man_t * pNew, * pOne; Vec_Int_t * vFanins, * vNodes; @@ -556,10 +559,17 @@ Gia_Man_t * Acb_NtkToGia2( Acb_Ntk_t * p ) Acb_NtkCleanObjCopies( p ); Acb_NtkForEachCi( p, iObj, i ) Acb_ObjSetCopy( p, iObj, Gia_ManAppendCi(pNew) ); + if ( vTargets ) + Vec_IntForEachEntry( vTargets, iObj, i ) + Acb_ObjSetCopy( p, iObj, Gia_ManAppendCi(pNew) ); + else + for ( i = 0; i < nTargets; i++ ) + Gia_ManAppendCi(pNew); vFanins = Vec_IntAlloc( 4 ); vNodes = Acb_NtkFindNodes2( p ); Vec_IntForEachEntry( vNodes, iObj, i ) - Acb_ObjSetCopy( p, iObj, Acb_ObjToGia2(pNew, p, iObj, vFanins) ); + if ( Acb_ObjCopy(p, iObj) == -1 ) // skip targets assigned above + Acb_ObjSetCopy( p, iObj, Acb_ObjToGia2(pNew, fUseBuf, p, iObj, vFanins, fUseXors) ); Vec_IntFree( vNodes ); Vec_IntFree( vFanins ); Acb_NtkForEachCo( p, iObj, i ) @@ -581,13 +591,19 @@ Gia_Man_t * Acb_NtkToGia2( Acb_Ntk_t * p ) SeeAlso [] ***********************************************************************/ -Vec_Int_t * Acb_NtkCollectCopies( Acb_Ntk_t * p, Gia_Man_t * pGia, Vec_Ptr_t ** pvNodesR ) +Vec_Int_t * Acb_NtkCollectCopies( Acb_Ntk_t * p, Gia_Man_t * pGia, Vec_Ptr_t ** pvNodesR, Vec_Bit_t ** pvPolar ) { - int i, iObj, iLit; + int i, iObj, iLit, nTargets = Vec_IntSize(&p->vTargets); Vec_Int_t * vObjs = Acb_NtkFindNodes2( p ); Vec_Int_t * vNodes = Vec_IntAlloc( Acb_NtkObjNum(p) ); Vec_Ptr_t * vNodesR = Vec_PtrStart( Gia_ManObjNum(pGia) ); Vec_Bit_t * vDriver = Vec_BitStart( Gia_ManObjNum(pGia) ); + Vec_Bit_t * vPolar = Vec_BitStart( Gia_ManObjNum(pGia) ); + Gia_ManForEachCiId( pGia, iObj, i ) + if ( i < Gia_ManCiNum(pGia) - nTargets ) + Vec_PtrWriteEntry( vNodesR, iObj, Abc_UtilStrsav(Acb_ObjNameStr(p, Acb_NtkCi(p, i))) ); + else + Vec_PtrWriteEntry( vNodesR, iObj, Abc_UtilStrsav(Acb_ObjNameStr(p, Vec_IntEntry(&p->vTargets, i-(Gia_ManCiNum(pGia) - nTargets)))) ); Gia_ManForEachCoId( pGia, iObj, i ) { Vec_BitWriteEntry( vDriver, Gia_ObjFaninId0(Gia_ManObj(pGia, iObj), iObj), 1 ); @@ -601,12 +617,14 @@ Vec_Int_t * Acb_NtkCollectCopies( Acb_Ntk_t * p, Gia_Man_t * pGia, Vec_Ptr_t ** { Vec_PtrWriteEntry( vNodesR, Abc_Lit2Var(iLit), Abc_UtilStrsav(Acb_ObjNameStr(p, iObj)) ); Vec_IntPush( vNodes, Abc_Lit2Var(iLit) ); + Vec_BitWriteEntry( vPolar, Abc_Lit2Var(iLit), Abc_LitIsCompl(iLit) ); } } Vec_BitFree( vDriver ); Vec_IntFree( vObjs ); Vec_IntSort( vNodes, 0 ); *pvNodesR = vNodesR; + *pvPolar = vPolar; return vNodes; } Vec_Int_t * Acb_NtkCollectUser( Acb_Ntk_t * p, Vec_Ptr_t * vUser ) @@ -642,23 +660,23 @@ Vec_Int_t * Acb_NtkCollectUser( Acb_Ntk_t * p, Vec_Ptr_t * vUser ) SeeAlso [] ***********************************************************************/ -int Acb_NtkExtract( char * pFileName0, char * pFileName1, int fVerbose, - Gia_Man_t ** ppGiaF, Gia_Man_t ** ppGiaG, Vec_Int_t ** pvNodes, Vec_Ptr_t ** pvNodesR ) +int Acb_NtkExtract( char * pFileName0, char * pFileName1, int fUseXors, int fVerbose, + Gia_Man_t ** ppGiaF, Gia_Man_t ** ppGiaG, int fUseBuf, Vec_Int_t ** pvNodes, Vec_Ptr_t ** pvNodesR, Vec_Bit_t ** pvPolar ) { - extern Acb_Ntk_t * Acb_VerilogSimpleRead( char * pFileName, char * pFileNameW ); Acb_Ntk_t * pNtkF = Acb_VerilogSimpleRead( pFileName0, NULL ); Acb_Ntk_t * pNtkG = Acb_VerilogSimpleRead( pFileName1, NULL ); - int RetValue = 0; + int RetValue = -1; if ( pNtkF && pNtkG ) { - Gia_Man_t * pGiaF = Acb_NtkToGia2( pNtkF ); - Gia_Man_t * pGiaG = Acb_NtkToGia2( pNtkG ); + int nTargets = Vec_IntSize(&pNtkF->vTargets); + Gia_Man_t * pGiaF = Acb_NtkToGia2( pNtkF, fUseBuf, fUseXors, &pNtkF->vTargets, 0 ); + Gia_Man_t * pGiaG = Acb_NtkToGia2( pNtkG, 0, 0, NULL, nTargets ); assert( Acb_NtkCiNum(pNtkF) == Acb_NtkCiNum(pNtkG) ); assert( Acb_NtkCoNum(pNtkF) == Acb_NtkCoNum(pNtkG) ); *ppGiaF = pGiaF; *ppGiaG = pGiaG; - *pvNodes = Acb_NtkCollectCopies( pNtkF, pGiaF, pvNodesR ); - RetValue = 1; + *pvNodes = Acb_NtkCollectCopies( pNtkF, pGiaF, pvNodesR, pvPolar ); + RetValue = nTargets; } if ( pNtkF ) Acb_ManFree( pNtkF->pDesign ); if ( pNtkG ) Acb_ManFree( pNtkG->pDesign ); @@ -676,9 +694,120 @@ int Acb_NtkExtract( char * pFileName0, char * pFileName1, int fVerbose, SeeAlso [] ***********************************************************************/ +Vec_Int_t * Abc_NtkCollectCopies( Abc_Ntk_t * p, Gia_Man_t * pGia, Vec_Ptr_t ** pvNodesR, Vec_Bit_t ** pvPolar ) +{ + int i, iObj, iLit; + Abc_Obj_t * pObj; + Vec_Ptr_t * vObjs = Abc_NtkDfs( p, 0 ); + Vec_Int_t * vNodes = Vec_IntAlloc( Abc_NtkObjNumMax(p) ); + Vec_Ptr_t * vNodesR = Vec_PtrStart( Gia_ManObjNum(pGia) ); + Vec_Bit_t * vDriver = Vec_BitStart( Gia_ManObjNum(pGia) ); + Vec_Bit_t * vPolar = Vec_BitStart( Gia_ManObjNum(pGia) ); + Gia_ManForEachCiId( pGia, iObj, i ) + Vec_PtrWriteEntry( vNodesR, iObj, Abc_UtilStrsav(Abc_ObjName(Abc_NtkCi(p, i))) ); + Gia_ManForEachCoId( pGia, iObj, i ) + { + Vec_BitWriteEntry( vDriver, Gia_ObjFaninId0(Gia_ManObj(pGia, iObj), iObj), 1 ); + Vec_PtrWriteEntry( vNodesR, iObj, Abc_UtilStrsav(Abc_ObjName(Abc_NtkCo(p, i))) ); + Vec_IntPush( vNodes, iObj ); + } + Vec_PtrForEachEntry( Abc_Obj_t *, vObjs, pObj, i ) + if ( (iLit = pObj->iTemp) >= 0 && Gia_ObjIsAnd(Gia_ManObj(pGia, Abc_Lit2Var(iLit))) ) + { + if ( !Vec_BitEntry(vDriver, Abc_Lit2Var(iLit)) && Vec_PtrEntry(vNodesR, Abc_Lit2Var(iLit)) == NULL ) + { + Vec_PtrWriteEntry( vNodesR, Abc_Lit2Var(iLit), Abc_UtilStrsav(Abc_ObjName(pObj)) ); + Vec_IntPush( vNodes, Abc_Lit2Var(iLit) ); + Vec_BitWriteEntry( vPolar, Abc_Lit2Var(iLit), Abc_LitIsCompl(iLit) ); + } + } + Vec_BitFree( vDriver ); + Vec_PtrFree( vObjs ); + Vec_IntSort( vNodes, 0 ); + *pvNodesR = vNodesR; + *pvPolar = vPolar; + return vNodes; +} +int Abc_ObjToGia2( Gia_Man_t * pNew, Abc_Ntk_t * p, Abc_Obj_t * pObj, Vec_Int_t * vTemp, int fUseXors ) +{ + Abc_Obj_t * pFanin; int k; + assert( Abc_ObjIsNode(pObj) ); + Vec_IntClear( vTemp ); + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + assert( pFanin->iTemp >= 0 ); + Vec_IntPush( vTemp, pFanin->iTemp ); + } + if ( Abc_ObjFaninNum(pObj) == 0 ) + return Abc_SopIsConst0( (char*)pObj->pData ) ? 0 : 1; + if ( Abc_ObjFaninNum(pObj) == 1 ) + return Abc_SopIsBuf( (char*)pObj->pData ) ? Vec_IntEntry(vTemp, 0) : Abc_LitNot(Vec_IntEntry(vTemp, 0)); + if ( Abc_ObjFaninNum(pObj) == 2 ) // nand2 + return Abc_LitNot( Gia_ManAppendAnd2( pNew, Vec_IntEntry(vTemp, 0), Vec_IntEntry(vTemp, 1) ) ); + assert( 0 ); + return -1; +} +Gia_Man_t * Abc_NtkToGia2( Abc_Ntk_t * p, int fUseXors ) +{ + Gia_Man_t * pNew, * pOne; + Vec_Int_t * vFanins; + Vec_Ptr_t * vNodes; + Abc_Obj_t * pObj; int i; + pNew = Gia_ManStart( 2 * Abc_NtkObjNumMax(p) + 1000 ); + pNew->pName = Abc_UtilStrsav(Abc_NtkName(p)); + Abc_NtkForEachObj( p, pObj, i ) + pObj->iTemp = -1; + Abc_NtkForEachCi( p, pObj, i ) + pObj->iTemp = Gia_ManAppendCi(pNew); + vFanins = Vec_IntAlloc( 4 ); + vNodes = Abc_NtkDfs( p, 0 ); + Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i ) + pObj->iTemp = Abc_ObjToGia2(pNew, p, pObj, vFanins, fUseXors); + Vec_PtrFree( vNodes ); + Vec_IntFree( vFanins ); + Abc_NtkForEachCo( p, pObj, i ) + Gia_ManAppendCo( pNew, Abc_ObjFanin0(pObj)->iTemp ); + pNew = Gia_ManCleanup( pOne = pNew ); + //Gia_ManUpdateCopy( &p->vObjCopy, pOne ); + Gia_ManStop( pOne ); + return pNew; +} +int Abc_NtkExtract( char * pFileName0, char * pFileName1, int fUseXors, int fVerbose, + Gia_Man_t ** ppGiaF, Gia_Man_t ** ppGiaG, Vec_Int_t ** pvNodes, Vec_Ptr_t ** pvNodesR, Vec_Bit_t ** pvPolar ) +{ + Abc_Ntk_t * pNtkF = Io_Read( pFileName0, Io_ReadFileType(pFileName0), 1, 0 ); + Abc_Ntk_t * pNtkG = Io_Read( pFileName1, Io_ReadFileType(pFileName1), 1, 0 ); + int RetValue = -1; + if ( pNtkF && pNtkG ) + { + Gia_Man_t * pGiaF = Abc_NtkToGia2( pNtkF, fUseXors ); + Gia_Man_t * pGiaG = Abc_NtkToGia2( pNtkG, 0 ); + assert( Abc_NtkCiNum(pNtkF) == Abc_NtkCiNum(pNtkG) ); + assert( Abc_NtkCoNum(pNtkF) == Abc_NtkCoNum(pNtkG) ); + *ppGiaF = pGiaF; + *ppGiaG = pGiaG; + *pvNodes = Abc_NtkCollectCopies( pNtkF, pGiaF, pvNodesR, pvPolar ); + RetValue = 0; + } + if ( pNtkF ) Abc_NtkDelete( pNtkF ); + if ( pNtkG ) Abc_NtkDelete( pNtkG ); + return RetValue; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ Vec_Int_t * Acb_NtkPlaces( char * pFileName, Vec_Ptr_t * vNames ) { - Vec_Int_t * vPlaces; int First = 1, Pos = -1; + Vec_Int_t * vPlaces; int First = 1, Pos = -1, fComment = 0; char * pTemp, * pBuffer = Extra_FileReadContents( pFileName ); char * pLimit = pBuffer + strlen(pBuffer); if ( pBuffer == NULL ) @@ -687,6 +816,13 @@ Vec_Int_t * Acb_NtkPlaces( char * pFileName, Vec_Ptr_t * vNames ) for ( pTemp = pBuffer; *pTemp; pTemp++ ) { if ( *pTemp == '\n' ) + fComment = 0; + if ( *pTemp == '/' && *(pTemp + 1) == '/' ) + fComment = 1; + if ( fComment ) + continue; + + if ( *pTemp == '\n' ) Pos = pTemp - pBuffer + 1; else if ( *pTemp == '(' ) { @@ -710,7 +846,7 @@ Vec_Int_t * Acb_NtkPlaces( char * pFileName, Vec_Ptr_t * vNames ) ABC_FREE( pBuffer ); return vPlaces; } -void Acb_NtkInsert( char * pFileNameIn, char * pFileNameOut, Vec_Ptr_t * vNames ) +void Acb_NtkInsert( char * pFileNameIn, char * pFileNameOut, Vec_Ptr_t * vNames, int fNumber ) { int i, k, Prev = 0, Pos, Pos2, iObj; Vec_Int_t * vPlaces; @@ -743,11 +879,27 @@ void Acb_NtkInsert( char * pFileNameIn, char * pFileNameOut, Vec_Ptr_t * vNames fputc( pBuffer[k], pFile ); fprintf( pFile, "\n\n" ); fprintf( pFile, " wire " ); - Vec_PtrForEachEntry( char *, vNames, pName, i ) - fprintf( pFile, " t_%d%s", i, i==Vec_PtrSize(vNames)-1 ? ";" : "," ); + if ( fNumber ) + { + Vec_PtrForEachEntry( char *, vNames, pName, i ) + fprintf( pFile, " t_%d%s", i, i==Vec_PtrSize(vNames)-1 ? ";" : "," ); + } + else + { + Vec_PtrForEachEntry( char *, vNames, pName, i ) + fprintf( pFile, " t%d_%s%s", i, pName, i==Vec_PtrSize(vNames)-1 ? ";" : "," ); + } fprintf( pFile, "\n\n" ); - Vec_PtrForEachEntry( char *, vNames, pName, i ) - fprintf( pFile, " buf( %s, t_%d );\n", pName, i ); + if ( fNumber ) + { + Vec_PtrForEachEntry( char *, vNames, pName, i ) + fprintf( pFile, " buf( %s, t_%d );\n", pName, i ); + } + else + { + Vec_PtrForEachEntry( char *, vNames, pName, i ) + fprintf( pFile, " buf( %s, t%d_%s );\n", pName, i, pName ); + } fprintf( pFile, "\n" ); for ( k = Pos2; pBuffer[k]; k++ ) fputc( pBuffer[k], pFile ); @@ -760,21 +912,114 @@ void Acb_NtkInsert( char * pFileNameIn, char * pFileNameOut, Vec_Ptr_t * vNames Synopsis [] Description [] - + SideEffects [] SeeAlso [] ***********************************************************************/ -void Acb_NtkRunSim( char * pFileName[4], int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fVerbose ) +void Acb_Ntk4CollectAdd( Acb_Ntk_t * pNtk, int iObj, Vec_Int_t * vRes, Vec_Int_t * vDists, int Dist ) +{ + if ( Acb_ObjSetTravIdCur(pNtk, iObj) ) + return; + Vec_IntWriteEntry( vDists, iObj, Dist ); + Vec_IntPush( vRes, iObj ); +} +void Acb_Ntk4CollectRing( Acb_Ntk_t * pNtk, Vec_Int_t * vStart, Vec_Int_t * vRes, Vec_Int_t * vDists ) +{ + int i, iObj; + Vec_IntForEachEntry( vStart, iObj, i ) + { + int k, iFanin, * pFanins, Weight = Vec_IntEntry(vDists, iObj); + Acb_ObjForEachFaninFast( pNtk, iObj, pFanins, iFanin, k ) + Acb_Ntk4CollectAdd( pNtk, iFanin, vRes, vDists, Weight + 1*(Acb_ObjFaninNum(pNtk, iObj) > 1) ); + Acb_ObjForEachFanout( pNtk, iObj, iFanin, k ) + Acb_Ntk4CollectAdd( pNtk, iFanin, vRes, vDists, Weight + 2*(Acb_ObjFaninNum(pNtk, iObj) > 1) ); + } +} +void Acb_Ntk4DumpWeightsInt( Acb_Ntk_t * pNtk, Vec_Int_t * vObjs, char * pFileName ) +{ + int i, iObj;//, Weight; + Vec_Int_t * vDists, * vStart, * vNexts; + FILE * pFile = fopen( pFileName, "wb" ); + if ( pFile == NULL ) + { + printf( "Canont open input file \"%s\".\n", pFileName ); + return; + } + vStart = Vec_IntAlloc( 100 ); + vNexts = Vec_IntAlloc( 100 ); + vDists = Vec_IntStart( Acb_NtkObjNumMax(pNtk) ); + Acb_NtkIncTravId( pNtk ); + Vec_IntForEachEntry( vObjs, iObj, i ) + { + Acb_ObjSetTravIdCur(pNtk, iObj); + Vec_IntWriteEntry( vDists, iObj, 1 ); + Vec_IntPush( vStart, iObj ); + } + while ( 1 ) + { + Acb_Ntk4CollectRing( pNtk, vStart, vNexts, vDists ); + if ( Vec_IntSize(vNexts) == 0 ) + break; + Vec_IntClear( vStart ); + ABC_SWAP( Vec_Int_t, *vStart, *vNexts ); + } + Vec_IntFree( vStart ); + Vec_IntFree( vNexts ); + // create weights +// Vec_IntForEachEntry( vDists, Weight, i ) +// if ( Weight && Acb_ObjNameStr(pNtk, i)[0] != '1' ) +// fprintf( pFile, "%s %d\n", Acb_ObjNameStr(pNtk, i), 10000+Weight ); + Acb_NtkForEachObj( pNtk, iObj ) + { + char * pName = Acb_ObjNameStr(pNtk, iObj); + int Weight = Vec_IntEntry(vDists, iObj); + if ( Weight == 0 ) + Weight = 10000; + fprintf( pFile, "%s %d\n", pName, 100000+Weight ); + } + + Vec_IntFree( vDists ); + fclose( pFile ); +} +void Acb_Ntk4DumpWeights( char * pFileNameIn, Vec_Ptr_t * vObjNames, char * pFileName ) { - extern int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fVerbose ); - extern void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fVerbose ); - char * pFileNames[4] = { pFileName[2], pFileName[1], NULL, pFileName[2] }; - if ( Gia_Sim4Try( pFileName[0], pFileName[1], pFileName[2], nWords, nBeam, LevL, LevU, fOrder, fFancy, fVerbose ) ) - Acb_NtkRunEco( pFileNames, 1, fVerbose ); + char * pName; int i, iObj; + Vec_Int_t * vObjs = Vec_IntAlloc( Vec_PtrSize(vObjNames) ); + Acb_Ntk_t * pNtkF = Acb_VerilogSimpleRead( pFileNameIn, NULL ); + Acb_NtkCreateFanout( pNtkF ); + Vec_PtrForEachEntry( char *, vObjNames, pName, i ) + { + Acb_NtkForEachObj( pNtkF, iObj ) + if ( !strcmp(Acb_ObjNameStr(pNtkF, iObj), pName) ) + Vec_IntPush( vObjs, iObj ); + } + Acb_Ntk4DumpWeightsInt( pNtkF, vObjs, pFileName ); + Acb_ManFree( pNtkF->pDesign ); + Vec_IntFree( vObjs ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Acb_NtkRunSim( char * pFileName[4], int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fRandom, int fUseWeights, int fVerbose, int fVeryVerbose ) +{ + extern int Gia_Sim4Try( char * pFileName0, char * pFileName1, char * pFileName2, int nWords, int nBeam, int LevL, int LevU, int fOrder, int fFancy, int fUseBuf, int fVerbose ); + extern void Acb_NtkRunEco( char * pFileNames[4], int fCheck, int fRandom, int fVerbose, int fVeryVerbose ); + char * pFileNames[4] = { pFileName[2], pFileName[1], fUseWeights ? (char *)"weights.txt" : NULL, pFileName[2] }; + if ( Gia_Sim4Try( pFileName[0], pFileName[1], pFileName[2], nWords, nBeam, LevL, LevU, fOrder, fFancy, fUseBuf, fVerbose ) ) + Acb_NtkRunEco( pFileNames, 1, fRandom, fVerbose, fVeryVerbose ); +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/base/acb/module.make b/src/base/acb/module.make index 46294f9f..ec78b3b0 100644 --- a/src/base/acb/module.make +++ b/src/base/acb/module.make @@ -5,4 +5,5 @@ SRC += src/base/acb/acbAbc.c \ src/base/acb/acbMfs.c \ src/base/acb/acbPush.c \ src/base/acb/acbSets.c \ + src/base/acb/acbTest.c \ src/base/acb/acbUtil.c diff --git a/src/base/cmd/cmdApi.c b/src/base/cmd/cmdApi.c index 2ee10229..73ebcf89 100644 --- a/src/base/cmd/cmdApi.c +++ b/src/base/cmd/cmdApi.c @@ -125,7 +125,7 @@ int Cmd_CommandHandleSpecial( Abc_Frame_t * pAbc, const char * sCommand ) if ( strstr(sCommand, "#ASSERT") ) { int Status = 0; - char * pNumb = strrchr( sCommand, '=' ); + char * pNumb = strrchr( (char *)sCommand, '=' ); if ( strstr(sCommand, "_PI_") ) { piCount = pNumb ? atoi(pNumb+1) : 0; diff --git a/src/base/io/io.c b/src/base/io/io.c index 49e1def1..a5cffbf4 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -231,6 +231,8 @@ int IoCommandRead( Abc_Frame_t * pAbc, int argc, char ** argv ) sprintf( Command, "read_constr %s", pFileName ); else if ( !strcmp( Extra_FileNameExtension(pFileName), "c" ) ) sprintf( Command, "so %s", pFileName ); + else if ( !strcmp( Extra_FileNameExtension(pFileName), "script" ) ) + sprintf( Command, "so %s", pFileName ); else if ( !strcmp( Extra_FileNameExtension(pFileName), "dsd" ) ) sprintf( Command, "dsd_load %s", pFileName ); if ( Command[0] ) diff --git a/src/base/main/mainInit.c b/src/base/main/mainInit.c index 7f5f13a8..d85d7b67 100644 --- a/src/base/main/mainInit.c +++ b/src/base/main/mainInit.c @@ -55,6 +55,8 @@ extern void Cba_Init( Abc_Frame_t * pAbc ); extern void Cba_End( Abc_Frame_t * pAbc ); extern void Pla_Init( Abc_Frame_t * pAbc ); extern void Pla_End( Abc_Frame_t * pAbc ); +extern void Sim_Init( Abc_Frame_t * pAbc ); +extern void Sim_End( Abc_Frame_t * pAbc ); extern void Test_Init( Abc_Frame_t * pAbc ); extern void Test_End( Abc_Frame_t * pAbc ); extern void Abc2_Init( Abc_Frame_t * pAbc ); @@ -115,6 +117,7 @@ void Abc_FrameInit( Abc_Frame_t * pAbc ) Bac_Init( pAbc ); Cba_Init( pAbc ); Pla_Init( pAbc ); + Sim_Init( pAbc ); Test_Init( pAbc ); Glucose_Init( pAbc ); for( p = s_InitializerStart ; p ; p = p->next ) @@ -154,6 +157,7 @@ void Abc_FrameEnd( Abc_Frame_t * pAbc ) Bac_End( pAbc ); Cba_End( pAbc ); Pla_End( pAbc ); + Sim_End( pAbc ); Test_End( pAbc ); Glucose_End( pAbc ); } diff --git a/src/base/main/mainReal.c b/src/base/main/mainReal.c index 180ec447..be099be4 100644 --- a/src/base/main/mainReal.c +++ b/src/base/main/mainReal.c @@ -145,8 +145,8 @@ int Abc_RealMain( int argc, char * argv[] ) } case 'l': { #ifndef WIN32 - int maxTime = atoi(globalUtilOptarg); - printf("Limiting time to %d seconds\n", maxTime); + rlim_t maxTime = atoi(globalUtilOptarg); + printf("Limiting time to %d seconds\n", (int)maxTime); struct rlimit limit = { maxTime, /* soft limit */ maxTime /* hard limit */ diff --git a/src/base/ver/verStream.c b/src/base/ver/verStream.c index 134bb2f9..4dca9ef6 100644 --- a/src/base/ver/verStream.c +++ b/src/base/ver/verStream.c @@ -454,7 +454,7 @@ char * Ver_StreamGetWord( Ver_Stream_t * p, char * pCharsToStop ) ***********************************************************************/ void Ver_StreamMove( Ver_Stream_t * p ) { - if ( !strncmp(p->pBufferCur+1, "z_g_", 4) ) + if ( !strncmp(p->pBufferCur+1, "z_g_", 4) || !strncmp(p->pBufferCur+1, "co_g", 3) ) while ( p->pBufferCur[0] != '(' ) p->pBufferCur++; } diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 2eb665bb..402ce21b 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -816,7 +816,7 @@ static Vec_Bit_t * Wlc_NtkMarkLimit( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) Vec_Ptr_t * vMults = Vec_PtrAlloc( 1000 ); Vec_Ptr_t * vFlops = Vec_PtrAlloc( 1000 ); Wlc_Obj_t * pObj; int i; - Int_Pair_t * pPair; + Int_Pair_t * pPair = NULL; if ( pPars->nLimit == ABC_INFINITY ) return NULL; diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 58c5d2ac..51f15597 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -1327,19 +1327,22 @@ usage: ******************************************************************************/ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Wln_NtkRetimeTest( char * pFileName, int fSkipSimple, int fVerbose ); + extern void Wln_NtkRetimeTest( char * pFileName, int fSkipSimple, int fDump, int fVerbose ); FILE * pFile; char * pFileName = NULL; int fSkipSimple = 0; - int c, fVerbose = 0; + int c, fDump = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "svh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "sdvh" ) ) != EOF ) { switch ( c ) { case 's': fSkipSimple ^= 1; break; + case 'd': + fDump ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -1352,7 +1355,7 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) if ( pAbc->pNdr ) { Vec_Int_t * vMoves; - Wln_Ntk_t * pNtk = Wln_NtkFromNdr( pAbc->pNdr ); + Wln_Ntk_t * pNtk = Wln_NtkFromNdr( pAbc->pNdr, fDump ); Wln_NtkRetimeCreateDelayInfo( pNtk ); if ( pNtk == NULL ) { @@ -1382,12 +1385,13 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } fclose( pFile ); - Wln_NtkRetimeTest( pFileName, fSkipSimple, fVerbose ); + Wln_NtkRetimeTest( pFileName, fSkipSimple, fDump, fVerbose ); return 0; usage: - Abc_Print( -2, "usage: %%retime [-svh]\n" ); + Abc_Print( -2, "usage: %%retime [-sdvh]\n" ); Abc_Print( -2, "\t performs retiming for the NDR design\n" ); Abc_Print( -2, "\t-s : toggle printing simple nodes [default = %s]\n", !fSkipSimple? "yes": "no" ); + Abc_Print( -2, "\t-d : toggle dumping the network in Verilog [default = %s]\n", fDump? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/wlc/wlcNdr.c b/src/base/wlc/wlcNdr.c index e0be9002..3212500f 100644 --- a/src/base/wlc/wlcNdr.c +++ b/src/base/wlc/wlcNdr.c @@ -504,9 +504,10 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) { int iObj = Wlc_ObjId(pNtk, pObj); int NameId = Wlc_ObjNameId(pNtk, iObj); - word Truth = Vec_WrdEntry(vTruths, NameId); + word Truth; if ( pObj->Type != WLC_OBJ_LUT || NameId == 0 ) continue; + Truth = Vec_WrdEntry(vTruths, NameId); assert( sizeof(void *) == 8 || Wlc_ObjFaninNum(pObj) < 6 ); Vec_WrdWriteEntry( pNtk->vLutTruths, iObj, Truth ); } diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 7d246c0f..ca5e615b 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -90,10 +90,11 @@ static char * Wlc_Names[WLC_OBJ_NUMBER+1] = { "addsub", // 56: adder/subtractor "sel", // 57: selector "dec", // 58: decoder + "LUT", // 59: lookup table NULL // 58: unused }; -char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return Wlc_Names[p->Type]; } +char * Wlc_ObjTypeName( Wlc_Obj_t * p ) { return p ? (p->Type < WLC_OBJ_NUMBER ? Wlc_Names[p->Type] : (char *)"out_of_bound") : (char *)"no_obj"; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -512,7 +513,7 @@ void Wlc_NtkPrintDistrib( Wlc_Ntk_t * p, int fTwoSides, int fVerbose ) Wlc_Obj_t * pObj, * pObjRange = NULL; int nCountRange = 0; Vec_Ptr_t * vTypes, * vOccurs; Vec_Int_t * vAnds = Vec_IntStart( WLC_OBJ_NUMBER ); - word Sign; + word Sign = 0; int i, k, s, s0, s1; if ( Wlc_NtkPoNum(p) != 2 ) fTwoSides = 0; @@ -945,8 +946,8 @@ void Wlc_NtkDupDfs_rec( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p, int iObj, Vec_Int_t * v return; if ( Wlc_ObjCopy(p, iObj) ) return; - //printf( "Visiting node %d with type %d (%s)\n", iObj, Wlc_NtkObj(p, iObj)->Type, Wlc_NtkObj(p, iObj)->Type < WLC_OBJ_NUMBER ? Wlc_Names[Wlc_NtkObj(p, iObj)->Type] : NULL ); pObj = Wlc_NtkObj( p, iObj ); + //printf( "Visiting node %16s (ID %6d) of type %5s (type ID %2d)\n", Wlc_ObjName(p, iObj), iObj, Wlc_ObjTypeName(pObj), Wlc_NtkObj(p, iObj)->Type ); assert( pObj->Type != WLC_OBJ_FF ); Wlc_ObjForEachFanin( pObj, iFanin, i ) Wlc_NtkDupDfs_rec( pNew, p, iFanin, vFanins ); diff --git a/src/base/wlc/wlcShow.c b/src/base/wlc/wlcShow.c index f43f8baa..59f42db5 100644 --- a/src/base/wlc/wlcShow.c +++ b/src/base/wlc/wlcShow.c @@ -362,7 +362,7 @@ void Wlc_NtkShow( Wlc_Ntk_t * p, Vec_Int_t * vBold ) FILE * pFile; char FileNameDot[200]; char * pName = Extra_FileDesignName(p->pName); - char * pSpec = p->pSpec ? Extra_FileDesignName(p->pSpec) : "unknown"; + char * pSpec = p->pSpec ? Extra_FileDesignName(p->pSpec) : (char *)"unknown"; sprintf( FileNameDot, "%s_%s.dot", pName, pSpec ); ABC_FREE( pName ); if ( strcmp(pSpec, "unknown") ) diff --git a/src/base/wln/wln.h b/src/base/wln/wln.h index 54150c56..510d74c1 100644 --- a/src/base/wln/wln.h +++ b/src/base/wln/wln.h @@ -163,6 +163,7 @@ static inline void Wln_ObjSetFanout( Wln_Ntk_t * p, int i, int f, int v static inline void Wln_NtkIncrementTravId( Wln_Ntk_t * p ) { if (!p->nTravIds++) Vec_IntFill(&p->vTravIds, Vec_IntCap(&p->vTypes), 0); } static inline void Wln_ObjSetTravIdCurrent( Wln_Ntk_t * p, int i ) { Vec_IntWriteEntry( &p->vTravIds, i, p->nTravIds ); } +static inline void Wln_ObjSetTravIdPrevious( Wln_Ntk_t * p, int i ) { Vec_IntWriteEntry( &p->vTravIds, i, p->nTravIds-1 ); } static inline int Wln_ObjIsTravIdCurrent( Wln_Ntk_t * p, int i ) { return (Vec_IntEntry(&p->vTravIds, i) == p->nTravIds); } static inline int Wln_ObjIsTravIdPrevious( Wln_Ntk_t * p, int i ) { return (Vec_IntEntry(&p->vTravIds, i) == p->nTravIds-1); } static inline int Wln_ObjCheckTravId( Wln_Ntk_t * p, int i ) { if ( Wln_ObjIsTravIdCurrent(p, i) ) return 1; Wln_ObjSetTravIdCurrent(p, i); return 0; } @@ -217,7 +218,7 @@ static inline int Wln_ObjRiToRo( Wln_Ntk_t * p, int i ) /*=== wlcNdr.c ========================================================*/ extern Wln_Ntk_t * Wln_ReadNdr( char * pFileName ); extern void Wln_WriteNdr( Wln_Ntk_t * pNtk, char * pFileName ); -extern Wln_Ntk_t * Wln_NtkFromNdr( void * pData ); +extern Wln_Ntk_t * Wln_NtkFromNdr( void * pData, int fDump ); extern void * Wln_NtkToNdr( Wln_Ntk_t * pNtk ); /*=== wlcNtk.c ========================================================*/ extern Wln_Ntk_t * Wln_NtkAlloc( char * pName, int nObjsMax ); @@ -225,6 +226,7 @@ extern void Wln_NtkFree( Wln_Ntk_t * p ); extern int Wln_NtkMemUsage( Wln_Ntk_t * p ); extern void Wln_NtkPrint( Wln_Ntk_t * p ); extern Wln_Ntk_t * Wln_NtkDupDfs( Wln_Ntk_t * p ); +extern int Wln_NtkIsAcyclic( Wln_Ntk_t * p ); extern void Wln_NtkCreateRefs( Wln_Ntk_t * p ); extern void Wln_NtkStartFaninMap( Wln_Ntk_t * p, Vec_Int_t * vFaninMap, int nMulti ); extern void Wln_NtkStartFanoutMap( Wln_Ntk_t * p, Vec_Int_t * vFanoutMap, Vec_Int_t * vFanoutNums, int nMulti ); diff --git a/src/base/wln/wlnNdr.c b/src/base/wln/wlnNdr.c index 60179ed4..eb685463 100644 --- a/src/base/wln/wlnNdr.c +++ b/src/base/wln/wlnNdr.c @@ -179,7 +179,7 @@ void Wln_NtkCheckIntegrity( void * pData ) } Vec_IntFree( vMap ); } -Wln_Ntk_t * Wln_NtkFromNdr( void * pData ) +Wln_Ntk_t * Wln_NtkFromNdr( void * pData, int fDump ) { Ndr_Data_t * p = (Ndr_Data_t *)pData; Vec_Int_t * vName2Obj, * vFanins = Vec_IntAlloc( 100 ); @@ -270,6 +270,11 @@ Wln_Ntk_t * Wln_NtkFromNdr( void * pData ) //Ndr_NtkPrintObjects( pNtk ); Wln_WriteVer( pNtk, "temp_ndr.v" ); printf( "Dumped design \"%s\" into file \"temp_ndr.v\".\n", pNtk->pName ); + if ( !Wln_NtkIsAcyclic(pNtk) ) + { + Wln_NtkFree(pNtk); + return NULL; + } // derive topological order pNtk = Wln_NtkDupDfs( pTemp = pNtk ); Wln_NtkFree( pTemp ); @@ -293,7 +298,7 @@ Wln_Ntk_t * Wln_NtkFromNdr( void * pData ) Wln_Ntk_t * Wln_ReadNdr( char * pFileName ) { void * pData = Ndr_Read( pFileName ); - Wln_Ntk_t * pNtk = pData ? Wln_NtkFromNdr( pData ) : NULL; + Wln_Ntk_t * pNtk = pData ? Wln_NtkFromNdr( pData, 0 ) : NULL; if ( pNtk ) return NULL; //char * ppNames[10] = { NULL, "a", "b", "c", "d", "e", "f", "g", "h", "i" }; //Ndr_WriteVerilog( NULL, pData, ppNames ); @@ -309,17 +314,17 @@ void Wln_ReadNdrTest() Wln_NtkStaticFanoutTest( pNtk ); Wln_NtkFree( pNtk ); } -void Wln_NtkRetimeTest( char * pFileName, int fSkipSimple, int fVerbose ) +void Wln_NtkRetimeTest( char * pFileName, int fSkipSimple, int fDump, int fVerbose ) { Vec_Int_t * vMoves; void * pData = Ndr_Read( pFileName ); - Wln_Ntk_t * pNtk = pData ? Wln_NtkFromNdr( pData ) : NULL; + Wln_Ntk_t * pNtk = pData ? Wln_NtkFromNdr( pData, fDump ) : NULL; + Ndr_Delete( pData ); if ( pNtk == NULL ) { printf( "Retiming network is not available.\n" ); return; } - Ndr_Delete( pData ); Wln_NtkRetimeCreateDelayInfo( pNtk ); vMoves = Wln_NtkRetime( pNtk, fSkipSimple, fVerbose ); //Vec_IntPrint( vMoves ); diff --git a/src/base/wln/wlnNtk.c b/src/base/wln/wlnNtk.c index a845b55e..5b3acb6f 100644 --- a/src/base/wln/wlnNtk.c +++ b/src/base/wln/wlnNtk.c @@ -129,6 +129,136 @@ void Wln_NtkPrint( Wln_Ntk_t * p ) printf( "\n" ); } + + +/**Function************************************************************* + + Synopsis [Detects combinational loops.] + + Description [This procedure is based on the idea suggested by Donald Chai. + As we traverse the network and visit the nodes, we need to distinquish + three types of nodes: (1) those that are visited for the first time, + (2) those that have been visited in this traversal but are currently not + on the traversal path, (3) those that have been visited and are currently + on the travesal path. When the node of type (3) is encountered, it means + that there is a combinational loop. To mark the three types of nodes, + two new values of the traversal IDs are used.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Wln_NtkIsAcyclic_rec( Wln_Ntk_t * p, int iObj ) +{ + int i, iFanin; + //printf( "Visiting node %d\n", iObj ); + // skip the node if it is already visited + if ( Wln_ObjIsTravIdPrevious(p, iObj) ) + return 1; + // check if the node is part of the combinational loop + if ( Wln_ObjIsTravIdCurrent(p, iObj) ) + { + fprintf( stdout, "Network contains combinational loop!\n" ); + fprintf( stdout, "Node %16s is encountered twice on the following path:\n", Wln_ObjName(p, iObj) ); + fprintf( stdout, "Node %16s (ID %6d) of type %5s (type ID %2d) ->\n", + Wln_ObjName(p, iObj), iObj, Abc_OperName(Wln_ObjType(p, iObj)), Wln_ObjType(p, iObj) ); + return 0; + } + // mark this node as a node on the current path + Wln_ObjSetTravIdCurrent( p, iObj ); + // quit if it is a CI or constant node + if ( Wln_ObjIsCi(p, iObj) || Wln_ObjIsFf(p, iObj) || Wln_ObjFaninNum(p, iObj) == 0 ) + { + // mark this node as a visited node + Wln_ObjSetTravIdPrevious( p, iObj ); + return 1; + } + // traverse the fanin's cone searching for the loop + Wln_ObjForEachFanin( p, iObj, iFanin, i ) + { + if ( !Wln_NtkIsAcyclic_rec(p, iFanin) ) + { + // return as soon as the loop is detected + fprintf( stdout, "Node %16s (ID %6d) of type %5s (type ID %2d) ->\n", + Wln_ObjName(p, iObj), iObj, Abc_OperName(Wln_ObjType(p, iObj)), Wln_ObjType(p, iObj) ); + return 0; + } + } + // mark this node as a visited node + Wln_ObjSetTravIdPrevious( p, iObj ); + return 1; +} +int Wln_NtkIsAcyclic( Wln_Ntk_t * p ) +{ + int fAcyclic, i, iObj, nUnvisited = 0 ; + // set the traversal ID for this DFS ordering + Wln_NtkIncrementTravId( p ); + Wln_NtkIncrementTravId( p ); + // iObj->TravId == pNet->nTravIds means "iObj is on the path" + // iObj->TravId == pNet->nTravIds - 1 means "iObj is visited but is not on the path" + // iObj->TravId < pNet->nTravIds - 1 means "iObj is not visited" + // traverse the network to detect cycles + fAcyclic = 1; + Wln_NtkForEachCo( p, iObj, i ) + { + // traverse the output logic cone + if ( (fAcyclic = Wln_NtkIsAcyclic_rec(p, iObj)) ) + continue; + // stop as soon as the first loop is detected + fprintf( stdout, "Primary output %16s (ID %6d)\n", Wln_ObjName(p, iObj), iObj ); + goto finish; + } + Wln_NtkForEachFf( p, iObj, i ) + { + // traverse the output logic cone + if ( (fAcyclic = Wln_NtkIsAcyclic_rec(p, iObj)) ) + continue; + // stop as soon as the first loop is detected + fprintf( stdout, "Flip-flop %16s (ID %6d)\n", Wln_ObjName(p, iObj), iObj ); + goto finish; + } + Wln_NtkForEachObj( p, iObj ) + nUnvisited += !Wln_ObjIsTravIdPrevious(p, iObj) && !Wln_ObjIsCi(p, iObj); + if ( nUnvisited ) + { + int nSinks = 0; + Wln_NtkCreateRefs(p); + printf( "The network has %d objects and %d (%6.2f %%) of them are not connected to the outputs.\n", + Wln_NtkObjNum(p), nUnvisited, 100.0*nUnvisited/Wln_NtkObjNum(p) ); + Wln_NtkForEachObj( p, iObj ) + if ( !Wln_ObjRefs(p, iObj) && !Wln_ObjIsCi(p, iObj) && !Wln_ObjIsCo(p, iObj) && !Wln_ObjIsFf(p, iObj) ) + nSinks++; + if ( nSinks ) + { + int nPrinted = 0; + printf( "These unconnected objects feed into %d sink objects without fanout:\n", nSinks ); + Wln_NtkForEachObj( p, iObj ) + if ( !Wln_ObjRefs(p, iObj) && !Wln_ObjIsCi(p, iObj) && !Wln_ObjIsCo(p, iObj) && !Wln_ObjIsFf(p, iObj) ) + { + fprintf( stdout, "Node %16s (ID %6d) of type %5s (type ID %2d)\n", + Wln_ObjName(p, iObj), iObj, Abc_OperName(Wln_ObjType(p, iObj)), Wln_ObjType(p, iObj) ); + if ( ++nPrinted == 5 ) + break; + } + if ( nPrinted < nSinks ) + printf( "...\n" ); + } + Wln_NtkForEachObj( p, iObj ) + if ( /*!Wln_ObjRefs(p, iObj) &&*/ !Wln_ObjIsTravIdPrevious(p, iObj) && !Wln_ObjIsCi(p, iObj) ) + { + // traverse the output logic cone + if ( (fAcyclic = Wln_NtkIsAcyclic_rec(p, iObj)) ) + continue; + // stop as soon as the first loop is detected + fprintf( stdout, "Unconnected object %s\n", Wln_ObjName(p, iObj) ); + goto finish; + } + } +finish: + return fAcyclic; +} + /**Function************************************************************* Synopsis [Duplicating network.] @@ -186,7 +316,7 @@ int Wln_NtkDupDfs_rec( Wln_Ntk_t * pNew, Wln_Ntk_t * p, int iObj ) return 0; if ( Wln_ObjCopy(p, iObj) ) return Wln_ObjCopy(p, iObj); - //printf( "Visiting node %d\n", iObj ); + //printf( "Visiting node %16s (ID %6d) of type %5s (type ID %2d)\n", Wln_ObjName(p, iObj), iObj, Abc_OperName(Wln_ObjType(p, iObj)), Wln_ObjType(p, iObj) ); assert( !Wln_ObjIsFf(p, iObj) ); Wln_ObjForEachFanin( p, iObj, iFanin, i ) Wln_NtkDupDfs_rec( pNew, p, iFanin ); diff --git a/src/base/wln/wlnRetime.c b/src/base/wln/wlnRetime.c index 3c4b4822..734ac194 100644 --- a/src/base/wln/wlnRetime.c +++ b/src/base/wln/wlnRetime.c @@ -487,6 +487,8 @@ void Wln_RetRetimeForward( Wln_Ret_t * p, Vec_Int_t * vSet ) Vec_IntForEachEntry( vSet, iObj, i ) { iFlop = Wln_RetRemoveOneFanin( p, iObj ); + if ( iFlop == -1 ) + continue; Wln_RetInsertOneFanout( p, iObj, iFlop ); } } @@ -496,6 +498,8 @@ void Wln_RetRetimeBackward( Wln_Ret_t * p, Vec_Int_t * vSet ) Vec_IntForEachEntry( vSet, iObj, i ) { iFlop = Wln_RetRemoveOneFanout( p, iObj ); + if ( iFlop == -1 ) + continue; Wln_RetInsertOneFanin( p, iObj, iFlop ); } } @@ -538,13 +542,18 @@ void Wln_RetAddToMoves( Wln_Ret_t * p, Vec_Int_t * vSet, int Delay, int fForward ***********************************************************************/ void Wln_NtkRetimeCreateDelayInfo( Wln_Ntk_t * pNtk ) { + int i, iObj; // if ( Wln_NtkHasInstId(pNtk) ) // Vec_IntErase( &pNtk->vInstIds ); if ( Wln_NtkHasInstId(pNtk) ) + { printf( "Using delays given by the user in the input file.\n" ); + Wln_NtkForEachObj( pNtk, iObj ) + if ( !Wln_ObjIsCio(pNtk, iObj) && !Wln_ObjIsConst(pNtk, iObj) && Wln_ObjInstId(pNtk, iObj) == 0 ) + printf( "Warning: Object %d of type %s has zero delay. Retiming will not work correctly.\n", iObj, Abc_OperName(Wln_ObjType(pNtk, iObj)) ); + } else { - int i, iObj; printf( "The design has no delay information.\n" ); Wln_NtkCleanInstId(pNtk); Wln_NtkForEachObj( pNtk, iObj ) diff --git a/src/bdd/llb/llb4Nonlin.c b/src/bdd/llb/llb4Nonlin.c index 155bc085..f8ee825e 100644 --- a/src/bdd/llb/llb4Nonlin.c +++ b/src/bdd/llb/llb4Nonlin.c @@ -1156,7 +1156,7 @@ Aig_Man_t * Llb_ReachableStates( Aig_Man_t * pAig ) Cudd_Quit( dd ); // convert - pNtkMuxes = Abc_NtkBddToMuxes( pNtk, 0 ); + pNtkMuxes = Abc_NtkBddToMuxes( pNtk, 0, 1000000 ); Abc_NtkDelete( pNtk ); pNtk = Abc_NtkStrash( pNtkMuxes, 0, 1, 0 ); Abc_NtkDelete( pNtkMuxes ); diff --git a/src/bdd/reo/reo.h b/src/bdd/reo/reo.h index a3ee844c..3916ac06 100644 --- a/src/bdd/reo/reo.h +++ b/src/bdd/reo/reo.h @@ -106,7 +106,7 @@ struct _reo_man int fVerbose; // the verbosity level int fVerify; // the flag toggling verification int fRemapUp; // the flag to enable remapping - int nIters; // the number of interations of sifting to perform + int nIters; // the number of iterations of sifting to perform // parameters given by the user when reordering is called DdManager * dd; // the CUDD BDD manager diff --git a/src/bool/dec/dec.h b/src/bool/dec/dec.h index 07bf9f6b..50c287f4 100644 --- a/src/bool/dec/dec.h +++ b/src/bool/dec/dec.h @@ -94,10 +94,10 @@ struct Dec_Man_t_ /// ITERATORS /// //////////////////////////////////////////////////////////////////////// -// interator throught the leaves +// iterator through the leaves #define Dec_GraphForEachLeaf( pGraph, pLeaf, i ) \ for ( i = 0; (i < (pGraph)->nLeaves) && (((pLeaf) = Dec_GraphNode(pGraph, i)), 1); i++ ) -// interator throught the internal nodes +// iterator through the internal nodes #define Dec_GraphForEachNode( pGraph, pAnd, i ) \ for ( i = (pGraph)->nLeaves; (i < (pGraph)->nSize) && (((pAnd) = Dec_GraphNode(pGraph, i)), 1); i++ ) @@ -133,7 +133,7 @@ extern unsigned Dec_GraphDeriveTruth( Dec_Graph_t * pGraph ); ***********************************************************************/ static inline Dec_Edge_t Dec_EdgeCreate( int Node, int fCompl ) { - Dec_Edge_t eEdge = { fCompl, Node }; + Dec_Edge_t eEdge = { (unsigned)fCompl, (unsigned)Node }; return eEdge; } diff --git a/src/bool/deco/deco.h b/src/bool/deco/deco.h index a1db47ce..2792e8d3 100644 --- a/src/bool/deco/deco.h +++ b/src/bool/deco/deco.h @@ -94,10 +94,10 @@ struct Dec_Man_t_ /// ITERATORS /// //////////////////////////////////////////////////////////////////////// -// interator throught the leaves +// iterator through the leaves #define Dec_GraphForEachLeaf( pGraph, pLeaf, i ) \ for ( i = 0; (i < (pGraph)->nLeaves) && (((pLeaf) = Dec_GraphNode(pGraph, i)), 1); i++ ) -// interator throught the internal nodes +// iterator through the internal nodes #define Dec_GraphForEachNode( pGraph, pAnd, i ) \ for ( i = (pGraph)->nLeaves; (i < (pGraph)->nSize) && (((pAnd) = Dec_GraphNode(pGraph, i)), 1); i++ ) @@ -122,7 +122,7 @@ struct Dec_Man_t_ ***********************************************************************/ static inline Dec_Edge_t Dec_EdgeCreate( int Node, int fCompl ) { - Dec_Edge_t eEdge = { fCompl, Node }; + Dec_Edge_t eEdge = { (unsigned)fCompl, (unsigned)Node }; return eEdge; } diff --git a/src/bool/kit/kit.h b/src/bool/kit/kit.h index 15b27fad..47f06403 100644 --- a/src/bool/kit/kit.h +++ b/src/bool/kit/kit.h @@ -194,7 +194,7 @@ static inline void Kit_SopShrink( Kit_Sop_t * cSop, int nCubesNew ) static inline void Kit_SopPushCube( Kit_Sop_t * cSop, unsigned uCube ) { cSop->pCubes[cSop->nCubes++] = uCube; } static inline void Kit_SopWriteCube( Kit_Sop_t * cSop, unsigned uCube, int i ) { cSop->pCubes[i] = uCube; } -static inline Kit_Edge_t Kit_EdgeCreate( int Node, int fCompl ) { Kit_Edge_t eEdge = { fCompl, Node }; return eEdge; } +static inline Kit_Edge_t Kit_EdgeCreate( int Node, int fCompl ) { Kit_Edge_t eEdge = { (unsigned)fCompl, (unsigned)Node }; return eEdge; } static inline unsigned Kit_EdgeToInt( Kit_Edge_t eEdge ) { return (eEdge.Node << 1) | eEdge.fCompl; } static inline Kit_Edge_t Kit_IntToEdge( unsigned Edge ) { return Kit_EdgeCreate( Edge >> 1, Edge & 1 ); } //static inline unsigned Kit_EdgeToInt_( Kit_Edge_t eEdge ) { return *(unsigned *)&eEdge; } @@ -566,6 +566,7 @@ extern Kit_Edge_t Kit_GraphAddNodeXor( Kit_Graph_t * pGraph, Kit_Edge_t eEd extern Kit_Edge_t Kit_GraphAddNodeMux( Kit_Graph_t * pGraph, Kit_Edge_t eEdgeC, Kit_Edge_t eEdgeT, Kit_Edge_t eEdgeE, int Type ); extern unsigned Kit_GraphToTruth( Kit_Graph_t * pGraph ); extern Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars, Vec_Int_t * vMemory ); +extern Kit_Graph_t * Kit_TruthToGraph2( unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory ); extern int Kit_GraphLeafDepth_rec( Kit_Graph_t * pGraph, Kit_Node_t * pNode, Kit_Node_t * pLeaf ); /*=== kitHop.c ==========================================================*/ //extern int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ); @@ -574,6 +575,7 @@ extern int Kit_GraphLeafDepth_rec( Kit_Graph_t * pGraph, Kit_Node_t //extern Hop_Obj_t * Kit_CoverToHop( Hop_Man_t * pMan, Vec_Int_t * vCover, int nVars, Vec_Int_t * vMemory ); /*=== kitIsop.c ==========================================================*/ extern int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth ); +extern int Kit_TruthIsop2( unsigned * puTruth0, unsigned * puTruth1, int nVars, Vec_Int_t * vMemory, int fTryBoth, int fReturnTt ); extern void Kit_TruthIsopPrint( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth ); extern void Kit_TruthIsopPrintCover( Vec_Int_t * vCover, int nVars, int fCompl ); /*=== kitPla.c ==========================================================*/ diff --git a/src/bool/kit/kitGraph.c b/src/bool/kit/kitGraph.c index 08dabc7e..0e548575 100644 --- a/src/bool/kit/kitGraph.c +++ b/src/bool/kit/kitGraph.c @@ -371,6 +371,34 @@ Kit_Graph_t * Kit_TruthToGraph( unsigned * pTruth, int nVars, Vec_Int_t * vMemor /**Function************************************************************* + Synopsis [Derives the factored form from the truth table.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Kit_Graph_t * Kit_TruthToGraph2( unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory ) +{ + Kit_Graph_t * pGraph; + int RetValue; + // derive SOP + RetValue = Kit_TruthIsop2( pTruth0, pTruth1, nVars, vMemory, 1, 0 ); // tried 1 and found not useful in "renode" + if ( RetValue == -1 ) + return NULL; + if ( Vec_IntSize(vMemory) > (1<<16) ) + return NULL; +// printf( "Isop size = %d.\n", Vec_IntSize(vMemory) ); + assert( RetValue == 0 || RetValue == 1 ); + // derive factored form + pGraph = Kit_SopFactor( vMemory, RetValue, nVars, vMemory ); + return pGraph; +} + +/**Function************************************************************* + Synopsis [Derives the maximum depth from the leaf to the root.] Description [] diff --git a/src/bool/kit/kitHop.c b/src/bool/kit/kitHop.c index a159a05a..4ac82ac9 100644 --- a/src/bool/kit/kitHop.c +++ b/src/bool/kit/kitHop.c @@ -100,6 +100,30 @@ int Kit_TruthToGia( Gia_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * Kit_GraphFree( pGraph ); return iLit; } +int Kit_TruthToGia2( Gia_Man_t * pMan, unsigned * pTruth0, unsigned * pTruth1, int nVars, Vec_Int_t * vMemory, Vec_Int_t * vLeaves, int fHash ) +{ + int iLit; + Kit_Graph_t * pGraph; + // transform truth table into the decomposition tree + if ( vMemory == NULL ) + { + vMemory = Vec_IntAlloc( 0 ); + pGraph = Kit_TruthToGraph2( pTruth0, pTruth1, nVars, vMemory ); + Vec_IntFree( vMemory ); + } + else + pGraph = Kit_TruthToGraph2( pTruth0, pTruth1, nVars, vMemory ); + if ( pGraph == NULL ) + { + printf( "Kit_TruthToGia2(): Converting truth table to AIG has failed for function:\n" ); + Kit_DsdPrintFromTruth( pTruth0, nVars ); printf( "\n" ); + Kit_DsdPrintFromTruth( pTruth1, nVars ); printf( "\n" ); + } + // derive the AIG for the decomposition tree + iLit = Kit_GraphToGia( pMan, pGraph, vLeaves, fHash ); + Kit_GraphFree( pGraph ); + return iLit; +} /**Function************************************************************* diff --git a/src/bool/kit/kitIsop.c b/src/bool/kit/kitIsop.c index 506da2e5..bc789945 100644 --- a/src/bool/kit/kitIsop.c +++ b/src/bool/kit/kitIsop.c @@ -52,6 +52,85 @@ static unsigned Kit_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, K SeeAlso [] ***********************************************************************/ +int Kit_TruthIsop2( unsigned * puTruth0, unsigned * puTruth1, int nVars, Vec_Int_t * vMemory, int fTryBoth, int fReturnTt ) +{ + Kit_Sop_t cRes, * pcRes = &cRes; + Kit_Sop_t cRes2, * pcRes2 = &cRes2; + unsigned * pResult; + int RetValue = 0; + assert( nVars >= 0 && nVars <= 16 ); + // prepare memory manager + Vec_IntClear( vMemory ); + Vec_IntGrow( vMemory, KIT_ISOP_MEM_LIMIT ); + // compute ISOP for the direct polarity + Kit_TruthNot( puTruth0, puTruth0, nVars ); + pResult = Kit_TruthIsop_rec( puTruth1, puTruth0, nVars, pcRes, vMemory ); + Kit_TruthNot( puTruth0, puTruth0, nVars ); + if ( pcRes->nCubes == -1 ) + { + vMemory->nSize = -1; + return -1; + } + assert( Kit_TruthIsImply( puTruth1, pResult, nVars ) ); + Kit_TruthNot( puTruth0, puTruth0, nVars ); + assert( Kit_TruthIsImply( pResult, puTruth0, nVars ) ); + Kit_TruthNot( puTruth0, puTruth0, nVars ); + if ( pcRes->nCubes == 0 || (pcRes->nCubes == 1 && pcRes->pCubes[0] == 0) ) + { + vMemory->pArray[0] = 0; + Vec_IntShrink( vMemory, pcRes->nCubes ); + return 0; + } + if ( fTryBoth ) + { + // compute ISOP for the complemented polarity + Kit_TruthNot( puTruth1, puTruth1, nVars ); + pResult = Kit_TruthIsop_rec( puTruth0, puTruth1, nVars, pcRes2, vMemory ); + Kit_TruthNot( puTruth1, puTruth1, nVars ); + if ( pcRes2->nCubes >= 0 ) + { + assert( Kit_TruthIsImply( puTruth0, pResult, nVars ) ); + Kit_TruthNot( puTruth1, puTruth1, nVars ); + assert( Kit_TruthIsImply( pResult, puTruth1, nVars ) ); + Kit_TruthNot( puTruth1, puTruth1, nVars ); + if ( pcRes->nCubes > pcRes2->nCubes || (pcRes->nCubes == pcRes2->nCubes && pcRes->nLits > pcRes2->nLits) ) + { + RetValue = 1; + pcRes = pcRes2; + } + } + } +// printf( "%d ", vMemory->nSize ); + // move the cover representation to the beginning of the memory buffer + if ( fReturnTt ) + { + int nWords = Kit_TruthWordNum( nVars ); + memmove( vMemory->pArray, pResult, nWords * sizeof(unsigned) ); + Vec_IntShrink( vMemory, nWords ); + } + else + { + memmove( vMemory->pArray, pcRes->pCubes, pcRes->nCubes * sizeof(unsigned) ); + Vec_IntShrink( vMemory, pcRes->nCubes ); + } + return RetValue; +} + + +/**Function************************************************************* + + Synopsis [Computes ISOP from TT.] + + Description [Returns the cover in vMemory. Uses the rest of array in vMemory + as an intermediate memory storage. Returns the cover with -1 cubes, if the + the computation exceeded the memory limit (KIT_ISOP_MEM_LIMIT words of + intermediate data).] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth ) { Kit_Sop_t cRes, * pcRes = &cRes; diff --git a/src/misc/extra/extraUtilFile.c b/src/misc/extra/extraUtilFile.c index eb1b7dce..38192c71 100644 --- a/src/misc/extra/extraUtilFile.c +++ b/src/misc/extra/extraUtilFile.c @@ -496,33 +496,16 @@ unsigned Extra_ReadBinary( char * Buffer ) ***********************************************************************/ void Extra_PrintBinary( FILE * pFile, unsigned Sign[], int nBits ) { - int Remainder, nWords; - int w, i; - - Remainder = (nBits%(sizeof(unsigned)*8)); - nWords = (nBits/(sizeof(unsigned)*8)) + (Remainder>0); - - for ( w = nWords-1; w >= 0; w-- ) - for ( i = ((w == nWords-1 && Remainder)? Remainder-1: 31); i >= 0; i-- ) - fprintf( pFile, "%c", '0' + (int)((Sign[w] & (1<<i)) > 0) ); - -// fprintf( pFile, "\n" ); + int i; + for ( i = nBits-1; i >= 0; i-- ) + fprintf( pFile, "%c", '0' + Abc_InfoHasBit(Sign, i) ); +// fprintf( pFile, "\n" ); } void Extra_PrintBinary2( FILE * pFile, unsigned Sign[], int nBits ) { - int Remainder, nWords; - int w, i; - - Remainder = (nBits%(sizeof(unsigned)*8)); - nWords = (nBits/(sizeof(unsigned)*8)) + (Remainder>0); - - for ( w = 0; w < nWords; w++ ) - { - int Limit = w == nWords-1 ? Remainder : 32; - for ( i = 0; i < Limit; i++ ) - fprintf( pFile, "%c", '0' + (int)((Sign[w] & (1<<i)) > 0) ); - } - + int i; + for ( i = 0; i < nBits; i++ ) + fprintf( pFile, "%c", '0' + Abc_InfoHasBit(Sign, i) ); // fprintf( pFile, "\n" ); } diff --git a/src/misc/extra/extraUtilMisc.c b/src/misc/extra/extraUtilMisc.c index 1df6c5a3..c38369cd 100644 --- a/src/misc/extra/extraUtilMisc.c +++ b/src/misc/extra/extraUtilMisc.c @@ -2594,6 +2594,19 @@ static inline void Extra_Transpose64Simple( word A[64], word B[64] ) if ( (A[i] >> k) & 1 ) B[k] |= ((word)1 << (63-i)); } +static inline void Extra_BitMatrixTransposeSimple( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut ) +{ + int i, k; + assert( Vec_WrdSize(vSimsIn) == nWordsIn * nWordsOut * 64 ); + assert( Vec_WrdSize(vSimsIn) == Vec_WrdSize(vSimsOut) ); + assert( Vec_WrdSize(vSimsIn) % nWordsIn == 0 ); + assert( Vec_WrdSize(vSimsOut) % nWordsOut == 0 ); + Vec_WrdFill( vSimsOut, Vec_WrdSize(vSimsOut), 0 ); + for ( i = 0; i < 64*nWordsOut; i++ ) + for ( k = 0; k < 64*nWordsIn; k++ ) + if ( Abc_InfoHasBit( (unsigned *)Vec_WrdEntryP(vSimsIn, i*nWordsIn), k ) ) + Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(vSimsOut, k*nWordsOut), i ); +} void Extra_Transpose32( unsigned a[32] ) { int j, k; @@ -2640,15 +2653,14 @@ void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * v { word * pM[64]; int i, y, x; assert( Vec_WrdSize(vSimsIn) == Vec_WrdSize(vSimsOut) ); - assert( Vec_WrdSize(vSimsIn) / nWordsIn == 64 * nWordsOut ); - assert( Vec_WrdSize(vSimsOut) / nWordsOut == 64 * nWordsIn ); - for ( y = 0; y < nWordsIn; y++ ) + assert( Vec_WrdSize(vSimsIn) == 64 * nWordsIn * nWordsOut ); for ( x = 0; x < nWordsOut; x++ ) + for ( y = 0; y < nWordsIn; y++ ) { for ( i = 0; i < 64; i++ ) { - pM[i] = Vec_WrdEntryP( vSimsOut, (64*y+i)*nWordsOut + x ); - pM[i][0] = Vec_WrdEntry ( vSimsIn, (64*x+i)*nWordsIn + y ); + pM[i] = Vec_WrdEntryP( vSimsOut, (64*y+63-i)*nWordsOut + x ); + pM[i][0] = Vec_WrdEntry ( vSimsIn, (64*x+63-i)*nWordsIn + y ); } Extra_Transpose64p( pM ); } @@ -2656,63 +2668,64 @@ void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * v void Extra_BitMatrixTransposePP( Vec_Ptr_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut ) { word * pM[64]; int i, y, x; - assert( Vec_WrdSize(vSimsOut) / nWordsOut == 64 * nWordsIn ); - for ( y = 0; y < nWordsIn; y++ ) + assert( Vec_PtrSize(vSimsIn) == 64 * nWordsOut ); + assert( Vec_WrdSize(vSimsOut) == 64 * nWordsOut * nWordsIn ); for ( x = 0; x < nWordsOut; x++ ) + for ( y = 0; y < nWordsIn; y++ ) { for ( i = 0; i < 64; i++ ) { - pM[i] = Vec_WrdEntryP( vSimsOut, (64*y+i)*nWordsOut + x ); - pM[i][0] = ((word *)Vec_PtrEntry( vSimsIn, 64*x+i ))[y]; + pM[i] = Vec_WrdEntryP( vSimsOut, (64*y+63-i)*nWordsOut + x ); + pM[i][0] = ((word *)Vec_PtrEntry( vSimsIn, 64*x+63-i ))[y]; } Extra_Transpose64p( pM ); } } -void Extra_BitMatrixTransposeTest() -{ - int nWordsIn = 1; - int nWordsOut = 2; - int i, k, nItems = 64 * nWordsIn * nWordsOut; - - Vec_Wrd_t * vSimsIn = Vec_WrdStart( nItems ); - Vec_Wrd_t * vSimsOut = Vec_WrdStart( nItems ); - - Abc_RandomW(1); - for ( i = 0; i < nItems; i++ ) - Vec_WrdWriteEntry( vSimsIn, i, Abc_RandomW(0) ); - - Extra_BitMatrixTransposeP( vSimsIn, nWordsIn, vSimsOut, nWordsOut ); - - nItems = Vec_WrdSize(vSimsIn) / nWordsIn; - for ( i = 0; i < nItems; i++ ) +void Extra_BitMatrixShow( Vec_Wrd_t * vSims, int nWords ) +{ + int i, k, nBits = Vec_WrdSize(vSims) / nWords; + for ( i = 0; i < nBits; i++ ) { if ( i%64 == 0 ) Abc_Print( 1, "\n" ); - for ( k = 0; k < nWordsIn; k++ ) + for ( k = 0; k < nWords; k++ ) { - Extra_PrintBinary( stdout, (unsigned *)Vec_WrdEntryP(vSimsIn, i*nWordsIn+k), 64 ); + Extra_PrintBinary2( stdout, (unsigned *)Vec_WrdEntryP(vSims, i*nWords+k), 64 ); Abc_Print( 1, " " ); } Abc_Print( 1, "\n" ); } Abc_Print( 1, "\n" ); +} +void Extra_BitMatrixTransposeTest() +{ + abctime clk = Abc_Clock(); - nItems = Vec_WrdSize(vSimsOut) / nWordsOut; - for ( i = 0; i < nItems; i++ ) - { - if ( i%64 == 0 ) - Abc_Print( 1, "\n" ); - for ( k = 0; k < nWordsOut; k++ ) - { - Extra_PrintBinary( stdout, (unsigned *)Vec_WrdEntryP(vSimsOut, i*nWordsOut+k), 64 ); - Abc_Print( 1, " " ); - } - Abc_Print( 1, "\n" ); - } - Abc_Print( 1, "\n" ); + int nWordsIn = 100; + int nWordsOut = 200; + int nItems = 64 * nWordsIn * nWordsOut; + + Vec_Wrd_t * vSimsIn = Vec_WrdStartRandom( nItems ); + Vec_Wrd_t * vSimsOut = Vec_WrdStart( nItems ); + Vec_Wrd_t * vSimsOut2 = Vec_WrdStart( nItems ); + + Extra_BitMatrixTransposeP ( vSimsIn, nWordsIn, vSimsOut, nWordsOut ); + Extra_BitMatrixTransposeSimple( vSimsIn, nWordsIn, vSimsOut2, nWordsOut ); + + if ( memcmp( Vec_WrdArray(vSimsOut), Vec_WrdArray(vSimsOut2), sizeof(word)*Vec_WrdSize(vSimsOut) ) ) + printf( "Verification failed.\n" ); + else + printf( "Verification succeeded.\n" ); + + //Extra_BitMatrixShow( vSimsIn, nWordsIn ); + //Extra_BitMatrixShow( vSimsOut, nWordsOut ); + //Extra_BitMatrixShow( vSimsOut2, nWordsOut ); Vec_WrdFree( vSimsIn ); Vec_WrdFree( vSimsOut ); + Vec_WrdFree( vSimsOut2 ); + + Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } //////////////////////////////////////////////////////////////////////// diff --git a/src/misc/util/abc_global.h b/src/misc/util/abc_global.h index aac1515b..d7c5bea7 100644 --- a/src/misc/util/abc_global.h +++ b/src/misc/util/abc_global.h @@ -480,30 +480,6 @@ static inline int Abc_PrimeCudd( unsigned int p ) } // end of Cudd_Prime -// Creates a sequence of random numbers. -// http://www.codeproject.com/KB/recipes/SimpleRNG.aspx - -#define NUMBER1 3716960521u -#define NUMBER2 2174103536u - -static inline unsigned Abc_Random( int fReset ) -{ - static unsigned int m_z = NUMBER1; - static unsigned int m_w = NUMBER2; - if ( fReset ) - { - m_z = NUMBER1; - m_w = NUMBER2; - } - m_z = 36969 * (m_z & 65535) + (m_z >> 16); - m_w = 18000 * (m_w & 65535) + (m_w >> 16); - return (m_z << 16) + m_w; -} -static inline word Abc_RandomW( int fReset ) -{ - return ((word)Abc_Random(fReset) << 32) | ((word)Abc_Random(fReset) << 0); -} - // the returned buffer has 32 unused bytes at the end, filled with zeros static inline void * Abc_FileReadContents( char * pFileName, int * pnFileSize ) { @@ -526,6 +502,12 @@ static inline void * Abc_FileReadContents( char * pFileName, int * pnFileSize ) fclose( pFile ); return (void *)pBuffer; } +static inline void Abc_ReverseOrder( int * pA, int nA ) +{ + int i; + for ( i = 0; i < nA/2; i++ ) + ABC_SWAP( int, pA[i], pA[nA-1-i] ); +} // sorting @@ -537,6 +519,8 @@ extern void Abc_QuickSort3( word * pData, int nSize, int fDecrease ); extern void Abc_QuickSortCostData( int * pCosts, int nSize, int fDecrease, word * pData, int * pResult ); extern int * Abc_QuickSortCost( int * pCosts, int nSize, int fDecrease ); +extern unsigned Abc_Random( int fReset ); +extern word Abc_RandomW( int fReset ); ABC_NAMESPACE_HEADER_END diff --git a/src/misc/util/utilSort.c b/src/misc/util/utilSort.c index 32154a7d..31890503 100644 --- a/src/misc/util/utilSort.c +++ b/src/misc/util/utilSort.c @@ -779,6 +779,41 @@ void Abc_QuickSortTest() ABC_FREE( pData2 ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ + +// Creates a sequence of random numbers. +// http://www.codeproject.com/KB/recipes/SimpleRNG.aspx + +#define NUMBER1 3716960521u +#define NUMBER2 2174103536u + +unsigned Abc_Random( int fReset ) +{ + static unsigned int m_z = NUMBER1; + static unsigned int m_w = NUMBER2; + if ( fReset ) + { + m_z = NUMBER1; + m_w = NUMBER2; + } + m_z = 36969 * (m_z & 65535) + (m_z >> 16); + m_w = 18000 * (m_w & 65535) + (m_w >> 16); + return (m_z << 16) + m_w; +} +word Abc_RandomW( int fReset ) +{ + return ((word)Abc_Random(fReset) << 32) | ((word)Abc_Random(fReset) << 0); +} //////////////////////////////////////////////////////////////////////// /// END OF FILE /// diff --git a/src/misc/util/utilTruth.h b/src/misc/util/utilTruth.h index 6fa5e0a3..e0ee1720 100644 --- a/src/misc/util/utilTruth.h +++ b/src/misc/util/utilTruth.h @@ -326,6 +326,16 @@ static inline void Abc_TtXor( word * pOut, word * pIn1, word * pIn2, int nWords, for ( w = 0; w < nWords; w++ ) pOut[w] = pIn1[w] ^ pIn2[w]; } +static inline void Abc_TtXorMask( word * pOut, word * pIn1, word * pIn2, word * pMask, int nWords, int fCompl ) +{ + int w; + if ( fCompl ) + for ( w = 0; w < nWords; w++ ) + pOut[w] = (pIn1[w] ^ pIn2[w]) & ~pMask[w]; + else + for ( w = 0; w < nWords; w++ ) + pOut[w] = (pIn1[w] ^ pIn2[w]) & pMask[w]; +} static inline void Abc_TtMux( word * pOut, word * pCtrl, word * pIn1, word * pIn0, int nWords ) { int w; @@ -443,6 +453,108 @@ static inline void Abc_TtIthVar( word * pOut, int iVar, int nVars ) /**Function************************************************************* + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_TtIsAndCompl( word * pOut, int fCompl, word * pIn1, int fCompl1, word * pIn2, int fCompl2, word * pCare, int nWords ) +{ + int w; + if ( fCompl ) + { + if ( fCompl1 ) + { + if ( fCompl2 ) + { + for ( w = 0; w < nWords; w++ ) + if ( (~pOut[w] & pCare[w]) != (~pIn1[w] & ~pIn2[w] & pCare[w]) ) + return 0; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( (~pOut[w] & pCare[w]) != (~pIn1[w] & pIn2[w] & pCare[w]) ) + return 0; + } + } + else + { + if ( fCompl2 ) + { + for ( w = 0; w < nWords; w++ ) + if ( (~pOut[w] & pCare[w]) != (pIn1[w] & ~pIn2[w] & pCare[w]) ) + return 0; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( (~pOut[w] & pCare[w]) != (pIn1[w] & pIn2[w] & pCare[w]) ) + return 0; + } + } + } + else + { + if ( fCompl1 ) + { + if ( fCompl2 ) + { + for ( w = 0; w < nWords; w++ ) + if ( (pOut[w] & pCare[w]) != (~pIn1[w] & ~pIn2[w] & pCare[w]) ) + return 0; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( (pOut[w] & pCare[w]) != (~pIn1[w] & pIn2[w] & pCare[w]) ) + return 0; + } + } + else + { + if ( fCompl2 ) + { + for ( w = 0; w < nWords; w++ ) + if ( (pOut[w] & pCare[w]) != (pIn1[w] & ~pIn2[w] & pCare[w]) ) + return 0; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( (pOut[w] & pCare[w]) != (pIn1[w] & pIn2[w] & pCare[w]) ) + return 0; + } + } + } + return 1; +} + +static inline int Abc_TtIsXorCompl( word * pOut, int fCompl, word * pIn1, word * pIn2, word * pCare, int nWords ) +{ + int w; + if ( fCompl ) + { + for ( w = 0; w < nWords; w++ ) + if ( (~pOut[w] & pCare[w]) != ((pIn1[w] ^ pIn2[w]) & pCare[w]) ) + return 0; + } + else + { + for ( w = 0; w < nWords; w++ ) + if ( ( pOut[w] & pCare[w]) != ((pIn1[w] ^ pIn2[w]) & pCare[w]) ) + return 0; + } + return 1; +} + + +/**Function************************************************************* + Synopsis [Compares Cof0 and Cof1.] Description [] @@ -1733,6 +1845,40 @@ static inline int Abc_TtCountOnesVecMask( word * x, word * pMask, int nWords, in Count += Abc_TtCountOnes( pMask[w] & x[w] ); return Count; } +static inline int Abc_TtCountOnesVecMask2( word * x0, word * x1, int fComp0, int fComp1, word * pMask, int nWords ) +{ + int w, Count = 0; + if ( !fComp0 && !fComp1 ) + for ( w = 0; w < nWords; w++ ) + Count += Abc_TtCountOnes( pMask[w] & x0[w] & x1[w] ); + else if ( fComp0 && !fComp1 ) + for ( w = 0; w < nWords; w++ ) + Count += Abc_TtCountOnes( pMask[w] & ~x0[w] & x1[w] ); + else if ( !fComp0 && fComp1 ) + for ( w = 0; w < nWords; w++ ) + Count += Abc_TtCountOnes( pMask[w] & x0[w] & ~x1[w] ); + else + for ( w = 0; w < nWords; w++ ) + Count += Abc_TtCountOnes( pMask[w] & ~x0[w] & ~x1[w] ); + return Count; +} +static inline int Abc_TtCountOnesVecXor( word * x, word * y, int nWords ) +{ + int w, Count = 0; + for ( w = 0; w < nWords; w++ ) + Count += Abc_TtCountOnes( x[w] ^ y[w] ); + return Count; +} +static inline int Abc_TtAndXorSum( word * pOut, word * pIn1, word * pIn2, int nWords ) +{ + int w, Count = 0; + for ( w = 0; w < nWords; w++ ) + { + pOut[w] &= pIn1[w] ^ pIn2[w]; + Count += Abc_TtCountOnes( pOut[w] ); + } + return Count; +} /**Function************************************************************* diff --git a/src/misc/vec/vecPtr.h b/src/misc/vec/vecPtr.h index 4b76b69f..ed2a481e 100644 --- a/src/misc/vec/vecPtr.h +++ b/src/misc/vec/vecPtr.h @@ -736,6 +736,14 @@ static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry ) return i; return -1; } +static inline int Vec_PtrFindStr( Vec_Ptr_t * p, char * Entry ) +{ + int i; + for ( i = 0; i < p->nSize; i++ ) + if ( p->pArray[i] && !strcmp((char *)p->pArray[i], Entry) ) + return i; + return -1; +} /**Function************************************************************* diff --git a/src/misc/vec/vecWec.h b/src/misc/vec/vecWec.h index 88ee3dd7..fdbded9c 100644 --- a/src/misc/vec/vecWec.h +++ b/src/misc/vec/vecWec.h @@ -68,6 +68,8 @@ struct Vec_Wec_t_ for ( i = LevelStart-1; (i >= LevelStop) && (((vVec) = Vec_WecEntry(vGlob, i)), 1); i-- ) #define Vec_WecForEachLevelTwo( vGlob1, vGlob2, vVec1, vVec2, i ) \ for ( i = 0; (i < Vec_WecSize(vGlob1)) && (((vVec1) = Vec_WecEntry(vGlob1, i)), 1) && (((vVec2) = Vec_WecEntry(vGlob2, i)), 1); i++ ) +#define Vec_WecForEachLevelDouble( vGlob, vVec1, vVec2, i ) \ + for ( i = 0; (i < Vec_WecSize(vGlob)) && (((vVec1) = Vec_WecEntry(vGlob, i)), 1) && (((vVec2) = Vec_WecEntry(vGlob, i+1)), 1); i += 2 ) //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// @@ -247,6 +249,9 @@ static inline int Vec_WecSizeUsedLimits( Vec_Wec_t * p, int iStart, int iStop ) ***********************************************************************/ static inline void Vec_WecShrink( Vec_Wec_t * p, int nSizeNew ) { + Vec_Int_t * vVec; int i; + Vec_WecForEachLevelStart( p, vVec, i, nSizeNew ) + Vec_IntShrink( vVec, 0 ); assert( p->nSize >= nSizeNew ); p->nSize = nSizeNew; } diff --git a/src/misc/vec/vecWrd.h b/src/misc/vec/vecWrd.h index 45df1c97..e123c054 100644 --- a/src/misc/vec/vecWrd.h +++ b/src/misc/vec/vecWrd.h @@ -160,6 +160,13 @@ static inline Vec_Wrd_t * Vec_WrdStartNatural( int nSize ) p->pArray[i] = i; return p; } +static inline Vec_Wrd_t * Vec_WrdStartRandom( int nSize ) +{ + Vec_Wrd_t * vSims = Vec_WrdStart( nSize ); int i; + for ( i = 0; i < nSize; i++ ) + vSims->pArray[i] = Abc_RandomW(0); + return vSims; +} /**Function************************************************************* diff --git a/src/opt/lpk/lpkCore.c b/src/opt/lpk/lpkCore.c index 728aa2dd..cc6087e8 100644 --- a/src/opt/lpk/lpkCore.c +++ b/src/opt/lpk/lpkCore.c @@ -546,7 +546,7 @@ p->timeEval += Abc_Clock() - clk; if ( pObjNew ) { int nGain = (int)pCut->nNodes - (int)pCut->nNodesDup - (nNodesAft - nNodesBef); - assert( nGain >= 1 - p->pPars->fZeroCost ); + //assert( nGain >= 1 - p->pPars->fZeroCost ); assert( Abc_ObjLevel(pObjNew) <= Required ); /* if ( nGain <= 0 ) diff --git a/src/opt/ret/retDelay.c b/src/opt/ret/retDelay.c index 92680cd0..d5b8834f 100644 --- a/src/opt/ret/retDelay.c +++ b/src/opt/ret/retDelay.c @@ -123,7 +123,7 @@ if ( fVerbose && !fInitial ) // quit after timing analysis if ( i == nIterLimit ) break; - // skip if 10 interations did not give improvement + // skip if 10 iterations did not give improvement if ( i - IterBest > 20 ) break; // skip if delay limit is reached diff --git a/src/proof/cec/cecSolve.c b/src/proof/cec/cecSolve.c index 02f14b76..af6a4fdb 100644 --- a/src/proof/cec/cecSolve.c +++ b/src/proof/cec/cecSolve.c @@ -673,6 +673,14 @@ p->timeSatUndec += Abc_Clock() - clk; SeeAlso [] ***********************************************************************/ +Abc_Cex_t * Cex_ManGenSimple( Cec_ManSat_t * p, int iOut ) +{ + Abc_Cex_t * pCex; + pCex = Abc_CexAlloc( 0, Gia_ManCiNum(p->pAig), 1 ); + pCex->iPo = iOut; + pCex->iFrame = 0; + return pCex; +} Abc_Cex_t * Cex_ManGenCex( Cec_ManSat_t * p, int iOut ) { Abc_Cex_t * pCex; @@ -715,10 +723,11 @@ void Cec_ManSatSolve( Cec_ManPat_t * pPat, Gia_Man_t * pAig, Cec_ParSat_t * pPar { if ( Gia_ObjIsConst0(Gia_ObjFanin0(pObj)) ) { - pObj->fMark0 = 0; - pObj->fMark1 = 1; + status = !Gia_ObjFaninC0(pObj); + pObj->fMark0 = (status == 0); + pObj->fMark1 = (status == 1); if ( pPars->fSaveCexes ) - Vec_PtrWriteEntry( pAig->vSeqModelVec, i, (Abc_Cex_t *)(ABC_PTRINT_T)1 ); + Vec_PtrWriteEntry( pAig->vSeqModelVec, i, status ? (Abc_Cex_t *)(ABC_PTRINT_T)1 : Cex_ManGenSimple(p, i) ); continue; } Bar_ProgressUpdate( pProgress, i, "SAT..." ); diff --git a/src/proof/fra/fraLcr.c b/src/proof/fra/fraLcr.c index 2d8b3d64..b9e2ccb4 100644 --- a/src/proof/fra/fraLcr.c +++ b/src/proof/fra/fraLcr.c @@ -604,7 +604,7 @@ p->timePart += Abc_Clock() - clk2; p->nNodesBeg = Aig_ManNodeNum(p->pAig); p->nRegsBeg = Aig_ManRegNum(p->pAig); - // perforn interative reduction of the partitions + // perform iterative reduction of the partitions p->fRefining = 1; for ( nIter = 0; p->fRefining; nIter++ ) { diff --git a/src/sat/bmc/bmcBmc3.c b/src/sat/bmc/bmcBmc3.c index 904a2d7f..6f408047 100644 --- a/src/sat/bmc/bmcBmc3.c +++ b/src/sat/bmc/bmcBmc3.c @@ -1772,6 +1772,7 @@ nTimeSat += clkSatRun; // check if other outputs failed under the same counter-example Saig_ManForEachPo( pAig, pObj, k ) { + Abc_Cex_t * pCexDup; if ( k >= Saig_ManPoNum(pAig) ) break; // skip solved outputs @@ -1807,7 +1808,10 @@ nTimeSat += clkSatRun; Gia_ManToBridgeResult( stdout, 0, pCexNew0, pCexNew0->iPo ); } // remember solved output - Vec_PtrWriteEntry( p->vCexes, k, Abc_CexDup(pCexNew, Saig_ManRegNum(pAig)) ); + //Vec_PtrWriteEntry( p->vCexes, k, Abc_CexDup(pCexNew, Saig_ManRegNum(pAig)) ); + pCexDup = Abc_CexDup(pCexNew, Saig_ManRegNum(pAig)); + pCexDup->iPo = k; + Vec_PtrWriteEntry( p->vCexes, k, pCexDup ); } Abc_CexFreeP( &pCexNew0 ); Abc_CexFree( pCexNew ); diff --git a/src/sat/bmc/bmcCexTools.c b/src/sat/bmc/bmcCexTools.c index 7a1c86a6..6cc29857 100644 --- a/src/sat/bmc/bmcCexTools.c +++ b/src/sat/bmc/bmcCexTools.c @@ -922,7 +922,7 @@ void Gia_ManCountCareBits( Gia_Man_t * p, Vec_Wec_t * vPats ) unsigned char * Mnist_ReadImages1_() { int Size = 60000 * 28 * 28 + 16; - unsigned char * pData = malloc( Size ); + unsigned char * pData = (unsigned char *)malloc( Size ); FILE * pFile = fopen( "train-images.idx3-ubyte", "rb" ); int RetValue = fread( pData, 1, Size, pFile ); assert( RetValue == Size ); diff --git a/src/sat/bmc/bmcFault.c b/src/sat/bmc/bmcFault.c index 823ba9d4..4a9ce415 100644 --- a/src/sat/bmc/bmcFault.c +++ b/src/sat/bmc/bmcFault.c @@ -1719,7 +1719,7 @@ finish: // dump the test suite if ( pPars->fDump ) { - char * pFileName = p->pSpec ? Extra_FileNameGenericAppend(p->pSpec, "_tests.txt") : "tests.txt"; + char * pFileName = p->pSpec ? Extra_FileNameGenericAppend(p->pSpec, "_tests.txt") : (char *)"tests.txt"; if ( pPars->fDumpDelay && pPars->Algo == 1 ) { Gia_ManDumpTestsDelay( vTests, Iter, pFileName, p ); @@ -1834,7 +1834,7 @@ finish: if ( pPars->fDumpUntest && status == l_True ) { abctime clk = Abc_Clock(); - char * pFileName = p->pSpec ? Extra_FileNameGenericAppend(p->pSpec, "_untest.txt") : "untest.txt"; + char * pFileName = p->pSpec ? Extra_FileNameGenericAppend(p->pSpec, "_untest.txt") : (char *)"untest.txt"; int nUntests = Gia_ManDumpUntests( pM, pCnf, pSat, nFuncVars, pFileName, pPars->fVerbose ); if ( p == pG ) printf( "Dumped %d untestable multiple faults into file \"%s\". ", nUntests, pFileName ); diff --git a/src/sat/bsat/satClause.h b/src/sat/bsat/satClause.h index d2ed3b75..74e685c3 100644 --- a/src/sat/bsat/satClause.h +++ b/src/sat/bsat/satClause.h @@ -88,7 +88,8 @@ static inline void Sat_MemWriteLimit( int * p, int nInts ) { p[0] = nI static inline int Sat_MemHandPage( Sat_Mem_t * p, cla h ) { return h >> p->nPageSize; } static inline int Sat_MemHandShift( Sat_Mem_t * p, cla h ) { return h & p->uPageMask; } -static inline int Sat_MemIntSize( int size, int lrn ) { return (size + 2 + lrn) & ~01; } +//static inline int Sat_MemIntSize( int size, int lrn ) { return (size + 2 + lrn) & ~01; } +static inline int Sat_MemIntSize( int size, int lrn ) { return 2*((size + 2 + lrn)/2); } static inline int Sat_MemClauseSize( clause * p ) { return Sat_MemIntSize(p->size, p->lrn); } static inline int Sat_MemClauseSize2( clause * p ) { return Sat_MemIntSize(p->size, 1); } |