/**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