| /**CFile**************************************************************** |
| |
| FileName [sscSim.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [SAT sweeping under constraints.] |
| |
| Synopsis [Simulation procedures.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 29, 2008.] |
| |
| Revision [$Id: sscSim.c,v 1.00 2008/07/29 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "sscInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| static inline word Ssc_Random() { return ((word)Gia_ManRandom(0) << 32) | ((word)Gia_ManRandom(0) << 0); } |
| static inline word Ssc_Random1( int Bit ) { return ((word)Gia_ManRandom(0) << 32) | ((word)Gia_ManRandom(0) << 1) | (word)Bit; } |
| static inline word Ssc_Random2() { return ((word)Gia_ManRandom(0) << 32) | ((word)Gia_ManRandom(0) << 2) | (word)2; } |
| |
| static inline void Ssc_SimAnd( word * pSim, word * pSim0, word * pSim1, int nWords, int fComp0, int fComp1 ) |
| { |
| int w; |
| if ( fComp0 && fComp1 ) for ( w = 0; w < nWords; w++ ) pSim[w] = ~(pSim0[w] | pSim1[w]); |
| else if ( fComp0 ) for ( w = 0; w < nWords; w++ ) pSim[w] = ~pSim0[w] & pSim1[w]; |
| else if ( fComp1 ) for ( w = 0; w < nWords; w++ ) pSim[w] = pSim0[w] &~pSim1[w]; |
| else for ( w = 0; w < nWords; w++ ) pSim[w] = pSim0[w] & pSim1[w]; |
| } |
| |
| static inline void Ssc_SimDup( word * pSim, word * pSim0, int nWords, int fComp0 ) |
| { |
| int w; |
| if ( fComp0 ) for ( w = 0; w < nWords; w++ ) pSim[w] = ~pSim0[w]; |
| else for ( w = 0; w < nWords; w++ ) pSim[w] = pSim0[w]; |
| } |
| |
| static inline void Ssc_SimConst( word * pSim, int nWords, int fComp0 ) |
| { |
| int w; |
| if ( fComp0 ) for ( w = 0; w < nWords; w++ ) pSim[w] = ~(word)0; |
| else for ( w = 0; w < nWords; w++ ) pSim[w] = 0; |
| } |
| |
| static inline void Ssc_SimOr( word * pSim, word * pSim0, int nWords, int fComp0 ) |
| { |
| int w; |
| if ( fComp0 ) for ( w = 0; w < nWords; w++ ) pSim[w] |= ~pSim0[w]; |
| else for ( w = 0; w < nWords; w++ ) pSim[w] |= pSim0[w]; |
| } |
| |
| static inline int Ssc_SimFindBitWord( word t ) |
| { |
| int n = 0; |
| if ( t == 0 ) return -1; |
| if ( (t & 0x00000000FFFFFFFF) == 0 ) { n += 32; t >>= 32; } |
| if ( (t & 0x000000000000FFFF) == 0 ) { n += 16; t >>= 16; } |
| if ( (t & 0x00000000000000FF) == 0 ) { n += 8; t >>= 8; } |
| if ( (t & 0x000000000000000F) == 0 ) { n += 4; t >>= 4; } |
| if ( (t & 0x0000000000000003) == 0 ) { n += 2; t >>= 2; } |
| if ( (t & 0x0000000000000001) == 0 ) { n++; } |
| return n; |
| } |
| static inline int Ssc_SimFindBit( word * pSim, int nWords ) |
| { |
| int w; |
| for ( w = 0; w < nWords; w++ ) |
| if ( pSim[w] ) |
| return 64*w + Ssc_SimFindBitWord(pSim[w]); |
| return -1; |
| } |
| |
| static inline int Ssc_SimCountBitsWord( word x ) |
| { |
| x = x - ((x >> 1) & ABC_CONST(0x5555555555555555)); |
| x = (x & ABC_CONST(0x3333333333333333)) + ((x >> 2) & ABC_CONST(0x3333333333333333)); |
| x = (x + (x >> 4)) & ABC_CONST(0x0F0F0F0F0F0F0F0F); |
| x = x + (x >> 8); |
| x = x + (x >> 16); |
| x = x + (x >> 32); |
| return (int)(x & 0xFF); |
| } |
| static inline int Ssc_SimCountBits( word * pSim, int nWords ) |
| { |
| int w, Counter = 0; |
| for ( w = 0; w < nWords; w++ ) |
| Counter += Ssc_SimCountBitsWord(pSim[w]); |
| return Counter; |
| } |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Vec_WrdDoubleSimInfo( Vec_Wrd_t * p, int nObjs ) |
| { |
| word * pArray = ABC_CALLOC( word, 2 * Vec_WrdSize(p) ); |
| int i, nWords = Vec_WrdSize(p) / nObjs; |
| assert( Vec_WrdSize(p) % nObjs == 0 ); |
| for ( i = 0; i < nObjs; i++ ) |
| memcpy( pArray + 2*i*nWords, p->pArray + i*nWords, sizeof(word) * nWords ); |
| ABC_FREE( p->pArray ); p->pArray = pArray; |
| p->nSize = p->nCap = 2*nWords*nObjs; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ssc_GiaResetPiPattern( Gia_Man_t * p, int nWords ) |
| { |
| p->iPatsPi = 0; |
| if ( p->vSimsPi == NULL ) |
| p->vSimsPi = Vec_WrdStart(0); |
| Vec_WrdFill( p->vSimsPi, nWords * Gia_ManCiNum(p), 0 ); |
| assert( nWords == Gia_ObjSimWords( p ) ); |
| } |
| void Ssc_GiaSavePiPattern( Gia_Man_t * p, Vec_Int_t * vPat ) |
| { |
| word * pSimPi; |
| int i; |
| assert( Vec_IntSize(vPat) == Gia_ManCiNum(p) ); |
| if ( p->iPatsPi == 64 * Gia_ObjSimWords(p) ) |
| Vec_WrdDoubleSimInfo( p->vSimsPi, Gia_ManCiNum(p) ); |
| assert( p->iPatsPi < 64 * Gia_ObjSimWords(p) ); |
| pSimPi = Gia_ObjSimPi( p, 0 ); |
| for ( i = 0; i < Gia_ManCiNum(p); i++, pSimPi += Gia_ObjSimWords(p) ) |
| if ( Vec_IntEntry(vPat, i) ) |
| Abc_InfoSetBit( (unsigned *)pSimPi, p->iPatsPi ); |
| p->iPatsPi++; |
| } |
| void Ssc_GiaRandomPiPattern( Gia_Man_t * p, int nWords, Vec_Int_t * vPivot ) |
| { |
| word * pSimPi; |
| int i, w; |
| Ssc_GiaResetPiPattern( p, nWords ); |
| pSimPi = Gia_ObjSimPi( p, 0 ); |
| for ( i = 0; i < Gia_ManPiNum(p); i++, pSimPi += nWords ) |
| { |
| pSimPi[0] = vPivot ? Ssc_Random1(Vec_IntEntry(vPivot, i)) : Ssc_Random2(); |
| for ( w = 1; w < nWords; w++ ) |
| pSimPi[w] = Ssc_Random(); |
| // if ( i < 10 ) |
| // Extra_PrintBinary( stdout, (unsigned *)pSimPi, 64 ), printf( "\n" ); |
| } |
| } |
| void Ssc_GiaPrintPiPatterns( Gia_Man_t * p ) |
| { |
| Gia_Obj_t * pObj; |
| word * pSimAig; |
| int i;//, nWords = Gia_ObjSimWords( p ); |
| Gia_ManForEachCi( p, pObj, i ) |
| { |
| pSimAig = Gia_ObjSimObj( p, pObj ); |
| // Extra_PrintBinary( stdout, pSimAig, 64 * nWords ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Transfer the simulation pattern from pCare to pAig.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Ssc_GiaTransferPiPattern( Gia_Man_t * pAig, Gia_Man_t * pCare, Vec_Int_t * vPivot ) |
| { |
| extern word * Ssc_GiaGetCareMask( Gia_Man_t * p ); |
| Gia_Obj_t * pObj; |
| int i, w, nWords = Gia_ObjSimWords( pCare ); |
| word * pCareMask = Ssc_GiaGetCareMask( pCare ); |
| int Count = Ssc_SimCountBits( pCareMask, nWords ); |
| word * pSimPiCare, * pSimPiAig; |
| if ( Count == 0 ) |
| { |
| ABC_FREE( pCareMask ); |
| return 0; |
| } |
| Ssc_GiaResetPiPattern( pAig, nWords ); |
| Gia_ManForEachCi( pCare, pObj, i ) |
| { |
| pSimPiAig = Gia_ObjSimPi( pAig, i ); |
| pSimPiCare = Gia_ObjSimObj( pCare, pObj ); |
| for ( w = 0; w < nWords; w++ ) |
| if ( Vec_IntEntry(vPivot, i) ) |
| pSimPiAig[w] = pSimPiCare[w] | ~pCareMask[w]; |
| else |
| pSimPiAig[w] = pSimPiCare[w] & pCareMask[w]; |
| } |
| ABC_FREE( pCareMask ); |
| return Count; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Ssc_GiaResetSimInfo( Gia_Man_t * p ) |
| { |
| assert( Vec_WrdSize(p->vSimsPi) % Gia_ManCiNum(p) == 0 ); |
| if ( p->vSims == NULL ) |
| p->vSims = Vec_WrdAlloc(0); |
| Vec_WrdFill( p->vSims, Gia_ObjSimWords(p) * Gia_ManObjNum(p), 0 ); |
| } |
| void Ssc_GiaSimRound( Gia_Man_t * p ) |
| { |
| Gia_Obj_t * pObj; |
| word * pSim, * pSim0, * pSim1; |
| int i, nWords = Gia_ObjSimWords(p); |
| Ssc_GiaResetSimInfo( p ); |
| assert( nWords == Vec_WrdSize(p->vSims) / Gia_ManObjNum(p) ); |
| // constant node |
| Ssc_SimConst( Gia_ObjSim(p, 0), nWords, 0 ); |
| // primary inputs |
| pSim = Gia_ObjSim( p, 1 ); |
| pSim0 = Gia_ObjSimPi( p, 0 ); |
| Gia_ManForEachCi( p, pObj, i ) |
| { |
| assert( pSim == Gia_ObjSimObj( p, pObj ) ); |
| Ssc_SimDup( pSim, pSim0, nWords, 0 ); |
| pSim += nWords; |
| pSim0 += nWords; |
| } |
| // intermediate nodes |
| pSim = Gia_ObjSim( p, 1+Gia_ManCiNum(p) ); |
| Gia_ManForEachAnd( p, pObj, i ) |
| { |
| assert( pSim == Gia_ObjSim( p, i ) ); |
| pSim0 = pSim - pObj->iDiff0 * nWords; |
| pSim1 = pSim - pObj->iDiff1 * nWords; |
| Ssc_SimAnd( pSim, pSim0, pSim1, nWords, Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj) ); |
| pSim += nWords; |
| } |
| // primary outputs |
| pSim = Gia_ObjSim( p, Gia_ManObjNum(p) - Gia_ManPoNum(p) ); |
| Gia_ManForEachPo( p, pObj, i ) |
| { |
| assert( pSim == Gia_ObjSimObj( p, pObj ) ); |
| pSim0 = pSim - pObj->iDiff0 * nWords; |
| Ssc_SimDup( pSim, pSim0, nWords, Gia_ObjFaninC0(pObj) ); |
| // Extra_PrintBinary( stdout, pSim, 64 ), printf( "\n" ); |
| pSim += nWords; |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns one SAT assignment of the PIs.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| word * Ssc_GiaGetCareMask( Gia_Man_t * p ) |
| { |
| Gia_Obj_t * pObj; |
| int i, nWords = Gia_ObjSimWords( p ); |
| word * pRes = ABC_FALLOC( word, nWords ); |
| Gia_ManForEachPo( p, pObj, i ) |
| Ssc_SimAnd( pRes, pRes, Gia_ObjSimObj(p, pObj), nWords, 0, 0 ); |
| return pRes; |
| } |
| Vec_Int_t * Ssc_GiaGetOneSim( Gia_Man_t * p ) |
| { |
| Vec_Int_t * vInit; |
| Gia_Obj_t * pObj; |
| int i, iBit, nWords = Gia_ObjSimWords( p ); |
| word * pRes = Ssc_GiaGetCareMask( p ); |
| iBit = Ssc_SimFindBit( pRes, nWords ); |
| ABC_FREE( pRes ); |
| if ( iBit == -1 ) |
| return NULL; |
| vInit = Vec_IntAlloc( 100 ); |
| Gia_ManForEachCi( p, pObj, i ) |
| Vec_IntPush( vInit, Abc_InfoHasBit((unsigned *)Gia_ObjSimObj(p, pObj), iBit) ); |
| return vInit; |
| } |
| Vec_Int_t * Ssc_GiaFindPivotSim( Gia_Man_t * p ) |
| { |
| Vec_Int_t * vInit; |
| Ssc_GiaRandomPiPattern( p, 1, NULL ); |
| Ssc_GiaSimRound( p ); |
| vInit = Ssc_GiaGetOneSim( p ); |
| return vInit; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Ssc_GiaCountCaresSim( Gia_Man_t * p ) |
| { |
| word * pRes = Ssc_GiaGetCareMask( p ); |
| int nWords = Gia_ObjSimWords( p ); |
| int Count = Ssc_SimCountBits( pRes, nWords ); |
| ABC_FREE( pRes ); |
| return Count; |
| } |
| int Ssc_GiaEstimateCare( Gia_Man_t * p, int nWords ) |
| { |
| Ssc_GiaRandomPiPattern( p, nWords, NULL ); |
| Ssc_GiaSimRound( p ); |
| return Ssc_GiaCountCaresSim( p ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |