| /**CFile**************************************************************** | |
| FileName [cecPat.c] | |
| SystemName [ABC: Logic synthesis and verification system.] | |
| PackageName [Combinational equivalence checking.] | |
| Synopsis [Simulation pattern manager.] | |
| Author [Alan Mishchenko] | |
| Affiliation [UC Berkeley] | |
| Date [Ver. 1.0. Started - June 20, 2005.] | |
| Revision [$Id: cecPat.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] | |
| ***********************************************************************/ | |
| #include "cecInt.h" | |
| ABC_NAMESPACE_IMPL_START | |
| //////////////////////////////////////////////////////////////////////// | |
| /// DECLARATIONS /// | |
| //////////////////////////////////////////////////////////////////////// | |
| //////////////////////////////////////////////////////////////////////// | |
| /// FUNCTION DEFINITIONS /// | |
| //////////////////////////////////////////////////////////////////////// | |
| /**Function************************************************************* | |
| Synopsis [] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| static inline void Cec_ManPatStoreNum( Cec_ManPat_t * p, int Num ) | |
| { | |
| unsigned x = (unsigned)Num; | |
| assert( Num >= 0 ); | |
| while ( x & ~0x7f ) | |
| { | |
| Vec_StrPush( p->vStorage, (char)((x & 0x7f) | 0x80) ); | |
| x >>= 7; | |
| } | |
| Vec_StrPush( p->vStorage, (char)x ); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| static inline int Cec_ManPatRestoreNum( Cec_ManPat_t * p ) | |
| { | |
| int ch, i, x = 0; | |
| for ( i = 0; (ch = Vec_StrEntry(p->vStorage, p->iStart++)) & 0x80; i++ ) | |
| x |= (ch & 0x7f) << (7 * i); | |
| return x | (ch << (7 * i)); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| static inline void Cec_ManPatStore( Cec_ManPat_t * p, Vec_Int_t * vPat ) | |
| { | |
| int i, Number, NumberPrev; | |
| assert( Vec_IntSize(vPat) > 0 ); | |
| Cec_ManPatStoreNum( p, Vec_IntSize(vPat) ); | |
| NumberPrev = Vec_IntEntry( vPat, 0 ); | |
| Cec_ManPatStoreNum( p, NumberPrev ); | |
| Vec_IntForEachEntryStart( vPat, Number, i, 1 ) | |
| { | |
| assert( NumberPrev < Number ); | |
| Cec_ManPatStoreNum( p, Number - NumberPrev ); | |
| NumberPrev = Number; | |
| } | |
| } | |
| /**Function************************************************************* | |
| Synopsis [] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| static inline void Cec_ManPatRestore( Cec_ManPat_t * p, Vec_Int_t * vPat ) | |
| { | |
| int i, Size, Number; | |
| Vec_IntClear( vPat ); | |
| Size = Cec_ManPatRestoreNum( p ); | |
| Number = Cec_ManPatRestoreNum( p ); | |
| Vec_IntPush( vPat, Number ); | |
| for ( i = 1; i < Size; i++ ) | |
| { | |
| Number += Cec_ManPatRestoreNum( p ); | |
| Vec_IntPush( vPat, Number ); | |
| } | |
| assert( Vec_IntSize(vPat) == Size ); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Derives satisfying assignment.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| int Cec_ManPatComputePattern_rec( Cec_ManSat_t * pSat, Gia_Man_t * p, Gia_Obj_t * pObj ) | |
| { | |
| int Counter = 0; | |
| if ( Gia_ObjIsTravIdCurrent(p, pObj) ) | |
| return 0; | |
| Gia_ObjSetTravIdCurrent(p, pObj); | |
| if ( Gia_ObjIsCi(pObj) ) | |
| { | |
| pObj->fMark1 = Cec_ObjSatVarValue( pSat, pObj ); | |
| return 1; | |
| } | |
| assert( Gia_ObjIsAnd(pObj) ); | |
| Counter += Cec_ManPatComputePattern_rec( pSat, p, Gia_ObjFanin0(pObj) ); | |
| Counter += Cec_ManPatComputePattern_rec( pSat, p, Gia_ObjFanin1(pObj) ); | |
| pObj->fMark1 = (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) & | |
| (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)); | |
| return Counter; | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Derives satisfying assignment.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Cec_ManPatComputePattern1_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat ) | |
| { | |
| if ( Gia_ObjIsTravIdCurrent(p, pObj) ) | |
| return; | |
| Gia_ObjSetTravIdCurrent(p, pObj); | |
| if ( Gia_ObjIsCi(pObj) ) | |
| { | |
| Vec_IntPush( vPat, Abc_Var2Lit( Gia_ObjCioId(pObj), pObj->fMark1==0 ) ); | |
| return; | |
| } | |
| assert( Gia_ObjIsAnd(pObj) ); | |
| if ( pObj->fMark1 == 1 ) | |
| { | |
| Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin0(pObj), vPat ); | |
| Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin1(pObj), vPat ); | |
| } | |
| else | |
| { | |
| assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 || | |
| (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 ); | |
| if ( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 ) | |
| Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin0(pObj), vPat ); | |
| else | |
| Cec_ManPatComputePattern1_rec( p, Gia_ObjFanin1(pObj), vPat ); | |
| } | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Derives satisfying assignment.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Cec_ManPatComputePattern2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat ) | |
| { | |
| if ( Gia_ObjIsTravIdCurrent(p, pObj) ) | |
| return; | |
| Gia_ObjSetTravIdCurrent(p, pObj); | |
| if ( Gia_ObjIsCi(pObj) ) | |
| { | |
| Vec_IntPush( vPat, Abc_Var2Lit( Gia_ObjCioId(pObj), pObj->fMark1==0 ) ); | |
| return; | |
| } | |
| assert( Gia_ObjIsAnd(pObj) ); | |
| if ( pObj->fMark1 == 1 ) | |
| { | |
| Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin0(pObj), vPat ); | |
| Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin1(pObj), vPat ); | |
| } | |
| else | |
| { | |
| assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 0 || | |
| (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 ); | |
| if ( (Gia_ObjFanin1(pObj)->fMark1 ^ Gia_ObjFaninC1(pObj)) == 0 ) | |
| Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin1(pObj), vPat ); | |
| else | |
| Cec_ManPatComputePattern2_rec( p, Gia_ObjFanin0(pObj), vPat ); | |
| } | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Derives satisfying assignment.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| int Cec_ManPatComputePattern3_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) | |
| { | |
| int Value0, Value1, Value; | |
| if ( Gia_ObjIsTravIdCurrent(p, pObj) ) | |
| return (pObj->fMark1 << 1) | pObj->fMark0; | |
| Gia_ObjSetTravIdCurrent(p, pObj); | |
| if ( Gia_ObjIsCi(pObj) ) | |
| { | |
| pObj->fMark0 = 1; | |
| pObj->fMark1 = 1; | |
| return GIA_UND; | |
| } | |
| assert( Gia_ObjIsAnd(pObj) ); | |
| Value0 = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin0(pObj) ); | |
| Value1 = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin1(pObj) ); | |
| Value = Gia_XsimAndCond( Value0, Gia_ObjFaninC0(pObj), Value1, Gia_ObjFaninC1(pObj) ); | |
| pObj->fMark0 = (Value & 1); | |
| pObj->fMark1 = ((Value >> 1) & 1); | |
| return Value; | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Derives satisfying assignment.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Cec_ManPatVerifyPattern( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPat ) | |
| { | |
| Gia_Obj_t * pTemp; | |
| int i, Value; | |
| Gia_ManIncrementTravId( p ); | |
| Vec_IntForEachEntry( vPat, Value, i ) | |
| { | |
| pTemp = Gia_ManCi( p, Abc_Lit2Var(Value) ); | |
| // assert( Abc_LitIsCompl(Value) != (int)pTemp->fMark1 ); | |
| if ( pTemp->fMark1 ) | |
| { | |
| pTemp->fMark0 = 0; | |
| pTemp->fMark1 = 1; | |
| } | |
| else | |
| { | |
| pTemp->fMark0 = 1; | |
| pTemp->fMark1 = 0; | |
| } | |
| Gia_ObjSetTravIdCurrent( p, pTemp ); | |
| } | |
| Value = Cec_ManPatComputePattern3_rec( p, Gia_ObjFanin0(pObj) ); | |
| Value = Gia_XsimNotCond( Value, Gia_ObjFaninC0(pObj) ); | |
| if ( Value != GIA_ONE ) | |
| Abc_Print( 1, "Cec_ManPatVerifyPattern(): Verification failed.\n" ); | |
| assert( Value == GIA_ONE ); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Cec_ManPatComputePattern4_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) | |
| { | |
| if ( Gia_ObjIsTravIdCurrent(p, pObj) ) | |
| return; | |
| Gia_ObjSetTravIdCurrent(p, pObj); | |
| pObj->fMark0 = 0; | |
| if ( Gia_ObjIsCi(pObj) ) | |
| return; | |
| assert( Gia_ObjIsAnd(pObj) ); | |
| Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin0(pObj) ); | |
| Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin1(pObj) ); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Cec_ManPatCleanMark0( Gia_Man_t * p, Gia_Obj_t * pObj ) | |
| { | |
| assert( Gia_ObjIsCo(pObj) ); | |
| Gia_ManIncrementTravId( p ); | |
| Cec_ManPatComputePattern4_rec( p, Gia_ObjFanin0(pObj) ); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| void Cec_ManPatSavePattern( Cec_ManPat_t * pMan, Cec_ManSat_t * p, Gia_Obj_t * pObj ) | |
| { | |
| Vec_Int_t * vPat; | |
| int nPatLits; | |
| abctime clkTotal = Abc_Clock(); | |
| // abctime clk; | |
| assert( Gia_ObjIsCo(pObj) ); | |
| pMan->nPats++; | |
| pMan->nPatsAll++; | |
| // compute values in the cone of influence | |
| //clk = Abc_Clock(); | |
| Gia_ManIncrementTravId( p->pAig ); | |
| nPatLits = Cec_ManPatComputePattern_rec( p, p->pAig, Gia_ObjFanin0(pObj) ); | |
| assert( (Gia_ObjFanin0(pObj)->fMark1 ^ Gia_ObjFaninC0(pObj)) == 1 ); | |
| pMan->nPatLits += nPatLits; | |
| pMan->nPatLitsAll += nPatLits; | |
| //pMan->timeFind += Abc_Clock() - clk; | |
| // compute sensitizing path | |
| //clk = Abc_Clock(); | |
| Vec_IntClear( pMan->vPattern1 ); | |
| Gia_ManIncrementTravId( p->pAig ); | |
| Cec_ManPatComputePattern1_rec( p->pAig, Gia_ObjFanin0(pObj), pMan->vPattern1 ); | |
| // compute sensitizing path | |
| Vec_IntClear( pMan->vPattern2 ); | |
| Gia_ManIncrementTravId( p->pAig ); | |
| Cec_ManPatComputePattern2_rec( p->pAig, Gia_ObjFanin0(pObj), pMan->vPattern2 ); | |
| // compare patterns | |
| vPat = Vec_IntSize(pMan->vPattern1) < Vec_IntSize(pMan->vPattern2) ? pMan->vPattern1 : pMan->vPattern2; | |
| pMan->nPatLitsMin += Vec_IntSize(vPat); | |
| pMan->nPatLitsMinAll += Vec_IntSize(vPat); | |
| //pMan->timeShrink += Abc_Clock() - clk; | |
| // verify pattern using ternary simulation | |
| //clk = Abc_Clock(); | |
| // Cec_ManPatVerifyPattern( p->pAig, pObj, vPat ); | |
| //pMan->timeVerify += Abc_Clock() - clk; | |
| // sort pattern | |
| //clk = Abc_Clock(); | |
| Vec_IntSort( vPat, 0 ); | |
| //pMan->timeSort += Abc_Clock() - clk; | |
| // save pattern | |
| Cec_ManPatStore( pMan, vPat ); | |
| pMan->timeTotal += Abc_Clock() - clkTotal; | |
| } | |
| void Cec_ManPatSavePatternCSat( Cec_ManPat_t * pMan, Vec_Int_t * vPat ) | |
| { | |
| // sort pattern | |
| Vec_IntSort( vPat, 0 ); | |
| // save pattern | |
| Cec_ManPatStore( pMan, vPat ); | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Packs patterns into array of simulation info.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| *************************************`**********************************/ | |
| int Cec_ManPatCollectTry( Vec_Ptr_t * vInfo, Vec_Ptr_t * vPres, int iBit, int * pLits, int nLits ) | |
| { | |
| unsigned * pInfo, * pPres; | |
| int i; | |
| for ( i = 0; i < nLits; i++ ) | |
| { | |
| pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i])); | |
| pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i])); | |
| if ( Abc_InfoHasBit( pPres, iBit ) && | |
| Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) ) | |
| return 0; | |
| } | |
| for ( i = 0; i < nLits; i++ ) | |
| { | |
| pInfo = (unsigned *)Vec_PtrEntry(vInfo, Abc_Lit2Var(pLits[i])); | |
| pPres = (unsigned *)Vec_PtrEntry(vPres, Abc_Lit2Var(pLits[i])); | |
| Abc_InfoSetBit( pPres, iBit ); | |
| if ( Abc_InfoHasBit( pInfo, iBit ) == Abc_LitIsCompl(pLits[i]) ) | |
| Abc_InfoXorBit( pInfo, iBit ); | |
| } | |
| return 1; | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Packs patterns into array of simulation info.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| Vec_Ptr_t * Cec_ManPatCollectPatterns( Cec_ManPat_t * pMan, int nInputs, int nWordsInit ) | |
| { | |
| Vec_Int_t * vPat = pMan->vPattern1; | |
| Vec_Ptr_t * vInfo, * vPres; | |
| int k, kMax = -1, nPatterns = 0; | |
| int iStartOld = pMan->iStart; | |
| int nWords = nWordsInit; | |
| int nBits = 32 * nWords; | |
| abctime clk = Abc_Clock(); | |
| vInfo = Vec_PtrAllocSimInfo( nInputs, nWords ); | |
| Gia_ManRandomInfo( vInfo, 0, 0, nWords ); | |
| vPres = Vec_PtrAllocSimInfo( nInputs, nWords ); | |
| Vec_PtrCleanSimInfo( vPres, 0, nWords ); | |
| while ( pMan->iStart < Vec_StrSize(pMan->vStorage) ) | |
| { | |
| nPatterns++; | |
| Cec_ManPatRestore( pMan, vPat ); | |
| for ( k = 1; k < nBits; k++, k += ((k % (32 * nWordsInit)) == 0) ) | |
| if ( Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) ) | |
| break; | |
| kMax = Abc_MaxInt( kMax, k ); | |
| if ( k == nBits-1 ) | |
| { | |
| Vec_PtrReallocSimInfo( vInfo ); | |
| Gia_ManRandomInfo( vInfo, 0, nWords, 2*nWords ); | |
| Vec_PtrReallocSimInfo( vPres ); | |
| Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords ); | |
| nWords *= 2; | |
| nBits *= 2; | |
| } | |
| } | |
| Vec_PtrFree( vPres ); | |
| pMan->nSeries = Vec_PtrReadWordsSimInfo(vInfo) / nWordsInit; | |
| pMan->timePack += Abc_Clock() - clk; | |
| pMan->timeTotal += Abc_Clock() - clk; | |
| pMan->iStart = iStartOld; | |
| if ( pMan->fVerbose ) | |
| { | |
| Abc_Print( 1, "Total = %5d. Max used = %5d. Full = %5d. Series = %d. ", | |
| nPatterns, kMax, nWordsInit*32, pMan->nSeries ); | |
| ABC_PRT( "Time", Abc_Clock() - clk ); | |
| Cec_ManPatPrintStats( pMan ); | |
| } | |
| return vInfo; | |
| } | |
| /**Function************************************************************* | |
| Synopsis [Packs patterns into array of simulation info.] | |
| Description [] | |
| SideEffects [] | |
| SeeAlso [] | |
| ***********************************************************************/ | |
| Vec_Ptr_t * Cec_ManPatPackPatterns( Vec_Int_t * vCexStore, int nInputs, int nRegs, int nWordsInit ) | |
| { | |
| Vec_Int_t * vPat; | |
| Vec_Ptr_t * vInfo, * vPres; | |
| int k, nSize, iStart, kMax = 0, nPatterns = 0; | |
| int nWords = nWordsInit; | |
| int nBits = 32 * nWords; | |
| // int RetValue; | |
| assert( nRegs <= nInputs ); | |
| vPat = Vec_IntAlloc( 100 ); | |
| vInfo = Vec_PtrAllocSimInfo( nInputs, nWords ); | |
| Vec_PtrCleanSimInfo( vInfo, 0, nWords ); | |
| Gia_ManRandomInfo( vInfo, nRegs, 0, nWords ); | |
| vPres = Vec_PtrAllocSimInfo( nInputs, nWords ); | |
| Vec_PtrCleanSimInfo( vPres, 0, nWords ); | |
| iStart = 0; | |
| while ( iStart < Vec_IntSize(vCexStore) ) | |
| { | |
| nPatterns++; | |
| // skip the output number | |
| iStart++; | |
| // get the number of items | |
| nSize = Vec_IntEntry( vCexStore, iStart++ ); | |
| if ( nSize <= 0 ) | |
| continue; | |
| // extract pattern | |
| Vec_IntClear( vPat ); | |
| for ( k = 0; k < nSize; k++ ) | |
| Vec_IntPush( vPat, Vec_IntEntry( vCexStore, iStart++ ) ); | |
| // add pattern to storage | |
| for ( k = 1; k < nBits; k++, k += ((k % (32 * nWordsInit)) == 0) ) | |
| if ( Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ) ) | |
| break; | |
| // k = kMax + 1; | |
| // RetValue = Cec_ManPatCollectTry( vInfo, vPres, k, (int *)Vec_IntArray(vPat), Vec_IntSize(vPat) ); | |
| // assert( RetValue == 1 ); | |
| kMax = Abc_MaxInt( kMax, k ); | |
| if ( k == nBits-1 ) | |
| { | |
| Vec_PtrReallocSimInfo( vInfo ); | |
| Vec_PtrCleanSimInfo( vInfo, nWords, 2*nWords ); | |
| Gia_ManRandomInfo( vInfo, nRegs, nWords, 2*nWords ); | |
| Vec_PtrReallocSimInfo( vPres ); | |
| Vec_PtrCleanSimInfo( vPres, nWords, 2*nWords ); | |
| nWords *= 2; | |
| nBits *= 2; | |
| } | |
| } | |
| // Abc_Print( 1, "packed %d patterns into %d vectors (out of %d)\n", nPatterns, kMax, nBits ); | |
| Vec_PtrFree( vPres ); | |
| Vec_IntFree( vPat ); | |
| return vInfo; | |
| } | |
| //////////////////////////////////////////////////////////////////////// | |
| /// END OF FILE /// | |
| //////////////////////////////////////////////////////////////////////// | |
| ABC_NAMESPACE_IMPL_END | |