| /**CFile**************************************************************** |
| |
| FileName [sbdSim.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [SAT-based optimization using internal don't-cares.] |
| |
| Synopsis [Simulation.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: sbdSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "sbdInt.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| static inline word * Sbd_ObjSims( Gia_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSims, p->iPatsPi * i ); } |
| static inline word * Sbd_ObjCtrl( Gia_Man_t * p, int i ) { return Vec_WrdEntryP( p->vSimsPi, p->iPatsPi * i ); } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [This does not work.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Sbd_GiaSimRoundBack2( Gia_Man_t * p ) |
| { |
| int nWords = p->iPatsPi; |
| Gia_Obj_t * pObj; |
| int w, i, Id; |
| // init primary outputs |
| Gia_ManForEachCoId( p, Id, i ) |
| for ( w = 0; w < nWords; w++ ) |
| Sbd_ObjSims(p, Id)[w] = Gia_ManRandomW(0); |
| // transfer to nodes |
| Gia_ManForEachCo( p, pObj, i ) |
| { |
| word * pSims = Sbd_ObjSims(p, Gia_ObjId(p, pObj)); |
| Abc_TtCopy( Sbd_ObjSims(p, Gia_ObjFaninId0p(p, pObj)), pSims, nWords, Gia_ObjFaninC0(pObj) ); |
| } |
| // simulate nodes |
| Gia_ManForEachAndReverse( p, pObj, i ) |
| { |
| word * pSims = Sbd_ObjSims(p, i); |
| word * pSims0 = Sbd_ObjSims(p, Gia_ObjFaninId0(pObj, i)); |
| word * pSims1 = Sbd_ObjSims(p, Gia_ObjFaninId1(pObj, i)); |
| word Rand = Gia_ManRandomW(0); |
| for ( w = 0; w < nWords; w++ ) |
| { |
| pSims0[w] = pSims[w] | Rand; |
| pSims1[w] = pSims[w] | ~Rand; |
| } |
| if ( Gia_ObjFaninC0(pObj) ) Abc_TtNot( pSims0, nWords ); |
| if ( Gia_ObjFaninC1(pObj) ) Abc_TtNot( pSims1, nWords ); |
| } |
| // primary inputs are initialized |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Tries to falsify a sequence of two-literal SAT problems.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Sbd_GiaSatOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj, int Value, int fFirst, int iPat ) |
| { |
| if ( Gia_ObjIsTravIdCurrent(p, pObj) ) |
| return (int)pObj->fMark0 == Value; |
| Gia_ObjSetTravIdCurrent(p, pObj); |
| pObj->fMark0 = Value; |
| if ( Gia_ObjIsCi(pObj) ) |
| { |
| word * pSims = Sbd_ObjSims(p, Gia_ObjId(p, pObj)); |
| if ( Abc_TtGetBit( pSims, iPat ) != Value ) |
| Abc_TtXorBit( pSims, iPat ); |
| return 1; |
| } |
| assert( Gia_ObjIsAnd(pObj) ); |
| assert( !Gia_ObjIsXor(pObj) ); |
| if ( Value ) |
| return Sbd_GiaSatOne_rec( p, Gia_ObjFanin0(pObj), !Gia_ObjFaninC0(pObj), fFirst, iPat ) && |
| Sbd_GiaSatOne_rec( p, Gia_ObjFanin1(pObj), !Gia_ObjFaninC1(pObj), fFirst, iPat ); |
| if ( fFirst ) |
| return Sbd_GiaSatOne_rec( p, Gia_ObjFanin0(pObj), Gia_ObjFaninC0(pObj), fFirst, iPat ); |
| else |
| return Sbd_GiaSatOne_rec( p, Gia_ObjFanin1(pObj), Gia_ObjFaninC1(pObj), fFirst, iPat ); |
| } |
| int Sbd_GiaSatOne( Gia_Man_t * p, Vec_Int_t * vPairs ) |
| { |
| int k, n, Var1, Var2, iPat = 0; |
| //Gia_ManSetPhase( p ); |
| Vec_IntForEachEntryDouble( vPairs, Var1, Var2, k ) |
| { |
| Gia_Obj_t * pObj1 = Gia_ManObj( p, Var1 ); |
| Gia_Obj_t * pObj2 = Gia_ManObj( p, Var2 ); |
| assert( Var2 > 0 ); |
| if ( Var1 == 0 ) |
| { |
| for ( n = 0; n < 2; n++ ) |
| { |
| Gia_ManIncrementTravId( p ); |
| if ( Sbd_GiaSatOne_rec(p, pObj2, !pObj2->fPhase, n, iPat) ) |
| { |
| iPat++; |
| break; |
| } |
| } |
| printf( "%c", n == 2 ? '.' : 'c' ); |
| } |
| else |
| { |
| for ( n = 0; n < 2; n++ ) |
| { |
| Gia_ManIncrementTravId( p ); |
| if ( Sbd_GiaSatOne_rec(p, pObj1, !pObj1->fPhase, n, iPat) && Sbd_GiaSatOne_rec(p, pObj2, pObj2->fPhase, n, iPat) ) |
| { |
| iPat++; |
| break; |
| } |
| Gia_ManIncrementTravId( p ); |
| if ( Sbd_GiaSatOne_rec(p, pObj1, pObj1->fPhase, n, iPat) && Sbd_GiaSatOne_rec(p, pObj2, !pObj2->fPhase, n, iPat) ) |
| { |
| iPat++; |
| break; |
| } |
| } |
| printf( "%c", n == 2 ? '.' : 'e' ); |
| } |
| if ( iPat == 64 * p->iPatsPi - 1 ) |
| break; |
| } |
| printf( "\n" ); |
| return iPat; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Sbd_GiaSimRoundBack( Gia_Man_t * p ) |
| { |
| extern void Sbd_GiaSimRound( Gia_Man_t * p, int fTry, Vec_Int_t ** pvMap ); |
| Vec_Int_t * vReprs = Vec_IntStart( Gia_ManObjNum(p) ); |
| Vec_Int_t * vPairs = Vec_IntAlloc( 1000 ); |
| Vec_Int_t * vMap; // maps each node into its class |
| int i, nConsts = 0, nClasses = 0, nPats; |
| Sbd_GiaSimRound( p, 0, &vMap ); |
| Gia_ManForEachAndId( p, i ) |
| { |
| if ( Vec_IntEntry(vMap, i) == 0 ) |
| Vec_IntPushTwo( vPairs, 0, i ), nConsts++; |
| else if ( Vec_IntEntry(vReprs, Vec_IntEntry(vMap, i)) == 0 ) |
| Vec_IntWriteEntry( vReprs, Vec_IntEntry(vMap, i), i ); |
| else if ( Vec_IntEntry(vReprs, Vec_IntEntry(vMap, i)) != -1 ) |
| { |
| Vec_IntPushTwo( vPairs, Vec_IntEntry(vReprs, Vec_IntEntry(vMap, i)), i ); |
| Vec_IntWriteEntry( vReprs, Vec_IntEntry(vMap, i), -1 ); |
| nClasses++; |
| } |
| } |
| Vec_IntFree( vMap ); |
| Vec_IntFree( vReprs ); |
| printf( "Constants = %d. Classes = %d.\n", nConsts, nClasses ); |
| |
| nPats = Sbd_GiaSatOne( p, vPairs ); |
| Vec_IntFree( vPairs ); |
| |
| printf( "Generated %d patterns.\n", nPats ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Sbd_GiaSimRound( Gia_Man_t * p, int fTry, Vec_Int_t ** pvMap ) |
| { |
| int nWords = p->iPatsPi; |
| Vec_Mem_t * vStore; |
| Gia_Obj_t * pObj; |
| Vec_Int_t * vMap = Vec_IntStart( Gia_ManObjNum(p) ); |
| int w, i, Id, fCompl, RetValue; |
| // init primary inputs |
| if ( fTry ) |
| { |
| Sbd_GiaSimRoundBack( p ); |
| Gia_ManForEachCiId( p, Id, i ) |
| Sbd_ObjSims(p, Id)[0] <<= 1; |
| } |
| else |
| { |
| Gia_ManForEachCiId( p, Id, i ) |
| for ( w = 0; w < nWords; w++ ) |
| Sbd_ObjSims(p, Id)[w] = Gia_ManRandomW(0) << !w; |
| } |
| // simulate internal nodes |
| vStore = Vec_MemAlloc( nWords, 16 ); // 2^12 N-word entries per page |
| Vec_MemHashAlloc( vStore, 1 << 16 ); |
| RetValue = Vec_MemHashInsert( vStore, Sbd_ObjSims(p, 0) ); // const zero |
| assert( RetValue == 0 ); |
| Gia_ManForEachAnd( p, pObj, i ) |
| { |
| word * pSims = Sbd_ObjSims(p, i); |
| if ( Gia_ObjIsXor(pObj) ) |
| Abc_TtXor( pSims, |
| Sbd_ObjSims(p, Gia_ObjFaninId0(pObj, i)), |
| Sbd_ObjSims(p, Gia_ObjFaninId1(pObj, i)), |
| nWords, |
| Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pObj) ); |
| else |
| Abc_TtAndCompl( pSims, |
| Sbd_ObjSims(p, Gia_ObjFaninId0(pObj, i)), Gia_ObjFaninC0(pObj), |
| Sbd_ObjSims(p, Gia_ObjFaninId1(pObj, i)), Gia_ObjFaninC1(pObj), |
| nWords ); |
| // hash sim info |
| fCompl = (int)(pSims[0] & 1); |
| if ( fCompl ) Abc_TtNot( pSims, nWords ); |
| Vec_IntWriteEntry( vMap, i, Vec_MemHashInsert(vStore, pSims) ); |
| if ( fCompl ) Abc_TtNot( pSims, nWords ); |
| } |
| Gia_ManForEachCo( p, pObj, i ) |
| { |
| word * pSims = Sbd_ObjSims(p, Gia_ObjId(p, pObj)); |
| Abc_TtCopy( pSims, Sbd_ObjSims(p, Gia_ObjFaninId0p(p, pObj)), nWords, Gia_ObjFaninC0(pObj) ); |
| // printf( "%d ", Abc_TtCountOnesVec(pSims, nWords) ); |
| assert( Gia_ObjPhase(pObj) == (int)(pSims[0] & 1) ); |
| } |
| // printf( "\n" ); |
| Vec_MemHashFree( vStore ); |
| Vec_MemFree( vStore ); |
| printf( "Objects = %6d. Unique = %6d.\n", Gia_ManAndNum(p), Vec_IntCountUnique(vMap) ); |
| if ( pvMap ) |
| *pvMap = vMap; |
| else |
| Vec_IntFree( vMap ); |
| } |
| void Sbd_GiaSimTest( Gia_Man_t * pGia ) |
| { |
| Gia_ManSetPhase( pGia ); |
| |
| // allocate simulation info |
| pGia->iPatsPi = 32; |
| pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * pGia->iPatsPi ); |
| pGia->vSimsPi = Vec_WrdStart( Gia_ManObjNum(pGia) * pGia->iPatsPi ); |
| |
| Gia_ManRandom( 1 ); |
| |
| Sbd_GiaSimRound( pGia, 0, NULL ); |
| Sbd_GiaSimRound( pGia, 0, NULL ); |
| Sbd_GiaSimRound( pGia, 0, NULL ); |
| |
| printf( "\n" ); |
| Sbd_GiaSimRound( pGia, 1, NULL ); |
| printf( "\n" ); |
| Sbd_GiaSimRound( pGia, 1, NULL ); |
| printf( "\n" ); |
| Sbd_GiaSimRound( pGia, 1, NULL ); |
| |
| Vec_WrdFreeP( &pGia->vSims ); |
| Vec_WrdFreeP( &pGia->vSimsPi ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |