/**CFile**************************************************************** FileName [bmcCexTools.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [SAT-based bounded model checking.] Synopsis [CEX analysis and optimization toolbox.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: bmcCexTools.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "bmc.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// static inline word Bmc_CexBitMask( int iBit ) { assert( iBit < 64 ); return ~(((word)1) << iBit); } static inline void Bmc_CexCopySim( Vec_Wrd_t * vSims, int iObjTo, int iObjFrom ) { Vec_WrdWriteEntry( vSims, iObjTo, iObjFrom ); } static inline void Bmc_CexAndSim( Vec_Wrd_t * vSims, int iObjTo, int i, int j ) { Vec_WrdWriteEntry( vSims, iObjTo, Vec_WrdEntry(vSims, i) & Vec_WrdEntry(vSims, j) ); } static inline void Bmc_CexOrSim( Vec_Wrd_t * vSims, int iObjTo, int i, int j ) { Vec_WrdWriteEntry( vSims, iObjTo, Vec_WrdEntry(vSims, i) | Vec_WrdEntry(vSims, j) ); } static inline int Bmc_CexSim( Vec_Wrd_t * vSims, int iObj, int i ) { return (Vec_WrdEntry(vSims, iObj) >> i) & 1; } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Bmc_CexBitCount( Abc_Cex_t * p, int nInputs ) { int k, Counter = 0, Counter2 = 0; if ( p == NULL ) { printf( "The counter example is NULL.\n" ); return -1; } for ( k = 0; k < p->nBits; k++ ) { Counter += Abc_InfoHasBit(p->pData, k); if ( (k - p->nRegs) % p->nPis < nInputs ) Counter2 += Abc_InfoHasBit(p->pData, k); } return Counter2; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Bmc_CexDumpStats( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare, Abc_Cex_t * pCexEss, Abc_Cex_t * pCexMin, abctime clk ) { int nInputs = Gia_ManPiNum(p); int nBitsTotal = (pCex->iFrame + 1) * nInputs; int nBitsCare = Bmc_CexBitCount(pCexCare, nInputs); int nBitsDC = nBitsTotal - nBitsCare; int nBitsEss = Bmc_CexBitCount(pCexEss, nInputs); int nBitsOpt = nBitsCare - nBitsEss; int nBitsMin = Bmc_CexBitCount(pCexMin, nInputs); FILE * pTable = fopen( "cex/stats.txt", "a+" ); fprintf( pTable, "%s ", p->pName ); fprintf( pTable, "%d ", nInputs ); fprintf( pTable, "%d ", Gia_ManRegNum(p) ); fprintf( pTable, "%d ", pCex->iFrame + 1 ); fprintf( pTable, "%d ", nBitsTotal ); fprintf( pTable, "%.2f ", 100.0 * nBitsDC / nBitsTotal ); fprintf( pTable, "%.2f ", 100.0 * nBitsOpt / nBitsTotal ); fprintf( pTable, "%.2f ", 100.0 * nBitsEss / nBitsTotal ); fprintf( pTable, "%.2f ", 100.0 * nBitsMin / nBitsTotal ); fprintf( pTable, "%.2f ", 1.0*clk/(CLOCKS_PER_SEC) ); fprintf( pTable, "\n" ); fclose( pTable ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Bmc_CexDumpAogStats( Gia_Man_t * p, abctime clk ) { FILE * pTable = fopen( "cex/aig_stats.txt", "a+" ); fprintf( pTable, "%s ", p->pName ); fprintf( pTable, "%d ", Gia_ManPiNum(p) ); fprintf( pTable, "%d ", Gia_ManAndNum(p) ); fprintf( pTable, "%d ", Gia_ManLevelNum(p) ); fprintf( pTable, "%.2f ", 1.0*clk/(CLOCKS_PER_SEC) ); fprintf( pTable, "\n" ); fclose( pTable ); } /**Function************************************************************* Synopsis [Performs initialized unrolling till the last frame.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Bmc_CexPerformUnrolling( Gia_Man_t * p, Abc_Cex_t * pCex ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pObjRo, * pObjRi; int i, k; assert( Gia_ManRegNum(p) > 0 ); pNew = Gia_ManStart( (pCex->iFrame + 1) * Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManConst0(p)->Value = 0; Gia_ManForEachRi( p, pObj, k ) pObj->Value = 0; Gia_ManHashAlloc( pNew ); for ( i = 0; i <= pCex->iFrame; i++ ) { Gia_ManForEachPi( p, pObj, k ) pObj->Value = Gia_ManAppendCi( pNew ); Gia_ManForEachRiRo( p, pObjRi, pObjRo, k ) pObjRo->Value = pObjRi->Value; Gia_ManForEachAnd( p, pObj, k ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) ); Gia_ManForEachCo( p, pObj, k ) pObj->Value = Gia_ObjFanin0Copy(pObj); } Gia_ManHashStop( pNew ); pObj = Gia_ManPo(p, pCex->iPo); Gia_ManAppendCo( pNew, pObj->Value ); // cleanup pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); return pNew; } void Bmc_CexPerformUnrollingTest( Gia_Man_t * p, Abc_Cex_t * pCex ) { Gia_Man_t * pNew; abctime clk = Abc_Clock(); pNew = Bmc_CexPerformUnrolling( p, pCex ); Gia_ManPrintStats( pNew, NULL ); Gia_AigerWrite( pNew, "unroll.aig", 0, 0 ); //Bmc_CexDumpAogStats( pNew, Abc_Clock() - clk ); Gia_ManStop( pNew ); printf( "CE-induced network is written into file \"unroll.aig\".\n" ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } /**Function************************************************************* Synopsis [Computes CE-induced network.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Bmc_CexBuildNetwork( Gia_Man_t * p, Abc_Cex_t * pCex ) { Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj, * pObjRo, * pObjRi; int fCompl0, fCompl1; int i, k, iBit = pCex->nRegs; // start the manager pNew = Gia_ManStart( 1000 ); pNew->pName = Abc_UtilStrsav( "unate" ); // set const0 Gia_ManConst0(p)->fMark0 = 0; Gia_ManConst0(p)->fMark1 = 1; Gia_ManConst0(p)->Value = ~0; // set init state Gia_ManForEachRi( p, pObj, k ) { pObj->fMark0 = 0; pObj->fMark1 = 1; pObj->Value = ~0; } Gia_ManHashAlloc( pNew ); for ( i = 0; i <= pCex->iFrame; i++ ) { // primary inputs Gia_ManForEachPi( p, pObj, k ) { pObj->fMark0 = Abc_InfoHasBit( pCex->pData, iBit++ ); pObj->fMark1 = 0; pObj->Value = Gia_ManAppendCi(pNew); } // transfer Gia_ManForEachRiRo( p, pObjRi, pObjRo, k ) { pObjRo->fMark0 = pObjRi->fMark0; pObjRo->fMark1 = pObjRi->fMark1; pObjRo->Value = pObjRi->Value; } // internal nodes Gia_ManForEachAnd( p, pObj, k ) { fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj); pObj->fMark0 = fCompl0 & fCompl1; if ( pObj->fMark0 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 & Gia_ObjFanin1(pObj)->fMark1; else if ( !fCompl0 && !fCompl1 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 | Gia_ObjFanin1(pObj)->fMark1; else if ( !fCompl0 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1; else if ( !fCompl1 ) pObj->fMark1 = Gia_ObjFanin1(pObj)->fMark1; else assert( 0 ); pObj->Value = ~0; if ( pObj->fMark1 ) continue; if ( pObj->fMark0 ) pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value ); else if ( !fCompl0 && !fCompl1 ) pObj->Value = Gia_ManHashOr( pNew, Gia_ObjFanin0(pObj)->Value, Gia_ObjFanin1(pObj)->Value ); else if ( !fCompl0 ) pObj->Value = Gia_ObjFanin0(pObj)->Value; else if ( !fCompl1 ) pObj->Value = Gia_ObjFanin1(pObj)->Value; else assert( 0 ); assert( pObj->Value > 0 ); } // combinational outputs Gia_ManForEachCo( p, pObj, k ) { pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1; pObj->Value = Gia_ObjFanin0(pObj)->Value; } } Gia_ManHashStop( pNew ); assert( iBit == pCex->nBits ); // create primary output pObj = Gia_ManPo(p, pCex->iPo); assert( pObj->fMark0 == 1 ); assert( pObj->fMark1 == 0 ); assert( pObj->Value > 0 ); Gia_ManAppendCo( pNew, pObj->Value ); // cleanup pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); return pNew; } void Bmc_CexBuildNetworkTest( Gia_Man_t * p, Abc_Cex_t * pCex ) { Gia_Man_t * pNew; abctime clk = Abc_Clock(); pNew = Bmc_CexBuildNetwork( p, pCex ); Gia_ManPrintStats( pNew, NULL ); Gia_AigerWrite( pNew, "unate.aig", 0, 0 ); //Bmc_CexDumpAogStats( pNew, Abc_Clock() - clk ); Gia_ManStop( pNew ); printf( "CE-induced network is written into file \"unate.aig\".\n" ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } /**Function************************************************************* Synopsis [Prints one counter-example.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Bmc_CexPrint( Abc_Cex_t * pCex, int nInputs, int fVerbose ) { int i, k, Count, iBit = pCex->nRegs; Abc_CexPrintStatsInputs( pCex, nInputs ); if ( !fVerbose ) return; for ( i = 0; i <= pCex->iFrame; i++ ) { Count = 0; printf( "%3d : ", i ); for ( k = 0; k < nInputs; k++ ) { Count += Abc_InfoHasBit(pCex->pData, iBit); printf( "%d", Abc_InfoHasBit(pCex->pData, iBit++) ); } printf( " %3d ", Count ); Count = 0; for ( ; k < pCex->nPis; k++ ) { Count += Abc_InfoHasBit(pCex->pData, iBit); printf( "%d", Abc_InfoHasBit(pCex->pData, iBit++) ); } printf( " %3d\n", Count ); } assert( iBit == pCex->nBits ); } /**Function************************************************************* Synopsis [Verifies the care set of the counter-example.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Bmc_CexVerify( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t * pCexCare ) { Gia_Obj_t * pObj; int i, k; assert( pCex->nRegs > 0 ); // assert( pCexCare->nRegs == 0 ); Gia_ObjTerSimSet0( Gia_ManConst0(p) ); Gia_ManForEachRi( p, pObj, k ) Gia_ObjTerSimSet0( pObj ); for ( i = 0; i <= pCex->iFrame; i++ ) { Gia_ManForEachPi( p, pObj, k ) { if ( !Abc_InfoHasBit( pCexCare->pData, pCexCare->nRegs + i * pCexCare->nPis + k ) ) Gia_ObjTerSimSetX( pObj ); else if ( Abc_InfoHasBit( pCex->pData, pCex->nRegs + i * pCex->nPis + k ) ) Gia_ObjTerSimSet1( pObj ); else Gia_ObjTerSimSet0( pObj ); } Gia_ManForEachRo( p, pObj, k ) Gia_ObjTerSimRo( p, pObj ); Gia_ManForEachAnd( p, pObj, k ) Gia_ObjTerSimAnd( pObj ); Gia_ManForEachCo( p, pObj, k ) Gia_ObjTerSimCo( pObj ); } pObj = Gia_ManPo( p, pCex->iPo ); return Gia_ObjTerSimGet1(pObj); } /**Function************************************************************* Synopsis [Computes internal states of the CEX.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Cex_t * Bmc_CexInnerStates( Gia_Man_t * p, Abc_Cex_t * pCex, Abc_Cex_t ** ppCexImpl, int fVerbose ) { Abc_Cex_t * pNew, * pNew2; Gia_Obj_t * pObj, * pObjRo, * pObjRi; int fCompl0, fCompl1; int i, k, iBit = 0; assert( pCex->nRegs > 0 ); // start the counter-example pNew = Abc_CexAlloc( 0, Gia_ManCiNum(p), pCex->iFrame + 1 ); pNew->iFrame = pCex->iFrame; pNew->iPo = pCex->iPo; // start the counter-example pNew2 = Abc_CexAlloc( 0, Gia_ManCiNum(p), pCex->iFrame + 1 ); pNew2->iFrame = pCex->iFrame; pNew2->iPo = pCex->iPo; // set initial state Gia_ManCleanMark01(p); // set const0 Gia_ManConst0(p)->fMark0 = 0; Gia_ManConst0(p)->fMark1 = 1; // set init state Gia_ManForEachRi( p, pObjRi, k ) { pObjRi->fMark0 = 0; pObjRi->fMark1 = 1; } iBit = pCex->nRegs; for ( i = 0; i <= pCex->iFrame; i++ ) { Gia_ManForEachPi( p, pObj, k ) pObj->fMark0 = Abc_InfoHasBit(pCex->pData, iBit++); Gia_ManForEachRiRo( p, pObjRi, pObjRo, k ) { pObjRo->fMark0 = pObjRi->fMark0; pObjRo->fMark1 = pObjRi->fMark1; } Gia_ManForEachCi( p, pObj, k ) { if ( pObj->fMark0 ) Abc_InfoSetBit( pNew->pData, pNew->nPis * i + k ); if ( pObj->fMark1 ) Abc_InfoSetBit( pNew2->pData, pNew2->nPis * i + k ); } Gia_ManForEachAnd( p, pObj, k ) { fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj); pObj->fMark0 = fCompl0 & fCompl1; if ( pObj->fMark0 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 & Gia_ObjFanin1(pObj)->fMark1; else if ( !fCompl0 && !fCompl1 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 | Gia_ObjFanin1(pObj)->fMark1; else if ( !fCompl0 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1; else if ( !fCompl1 ) pObj->fMark1 = Gia_ObjFanin1(pObj)->fMark1; else assert( 0 ); } Gia_ManForEachCo( p, pObj, k ) { pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1; } /* // print input/state/output printf( "%3d : ", i ); Gia_ManForEachPi( p, pObj, k ) printf( "%d", pObj->fMark0 ); printf( " " ); Gia_ManForEachRo( p, pObj, k ) printf( "%d", pObj->fMark0 ); printf( " " ); Gia_ManForEachPo( p, pObj, k ) printf( "%d", pObj->fMark0 ); printf( "\n" ); */ } assert( iBit == pCex->nBits ); assert( Gia_ManPo(p, pCex->iPo)->fMark0 == 1 ); printf( "Inner states: " ); Bmc_CexPrint( pNew, Gia_ManPiNum(p), fVerbose ); printf( "Implications: " ); Bmc_CexPrint( pNew2, Gia_ManPiNum(p), fVerbose ); if ( ppCexImpl ) *ppCexImpl = pNew2; else Abc_CexFree( pNew2 ); return pNew; } /**Function************************************************************* Synopsis [Computes care bits of the CEX.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Bmc_CexCareBits_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) { int fCompl0, fCompl1; if ( Gia_ObjIsConst0(pObj) ) return; if ( pObj->fMark1 ) return; pObj->fMark1 = 1; if ( Gia_ObjIsCi(pObj) ) return; assert( Gia_ObjIsAnd(pObj) ); fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj); if ( pObj->fMark0 ) { assert( fCompl0 == 1 && fCompl1 == 1 ); Bmc_CexCareBits_rec( p, Gia_ObjFanin0(pObj) ); Bmc_CexCareBits_rec( p, Gia_ObjFanin1(pObj) ); } else { assert( fCompl0 == 0 || fCompl1 == 0 ); if ( fCompl0 == 0 ) Bmc_CexCareBits_rec( p, Gia_ObjFanin0(pObj) ); if ( fCompl1 == 0 ) Bmc_CexCareBits_rec( p, Gia_ObjFanin1(pObj) ); } } void Bmc_CexCareBits2_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) { int fCompl0, fCompl1; if ( Gia_ObjIsConst0(pObj) ) return; if ( pObj->fMark1 ) return; pObj->fMark1 = 1; if ( Gia_ObjIsCi(pObj) ) return; assert( Gia_ObjIsAnd(pObj) ); fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj); if ( pObj->fMark0 ) { assert( fCompl0 == 1 && fCompl1 == 1 ); Bmc_CexCareBits2_rec( p, Gia_ObjFanin0(pObj) ); Bmc_CexCareBits2_rec( p, Gia_ObjFanin1(pObj) ); } else { assert( fCompl0 == 0 || fCompl1 == 0 ); if ( fCompl0 == 0 ) Bmc_CexCareBits2_rec( p, Gia_ObjFanin0(pObj) ); /**/ else /**/ if ( fCompl1 == 0 ) Bmc_CexCareBits2_rec( p, Gia_ObjFanin1(pObj) ); } } Abc_Cex_t * Bmc_CexCareBits( Gia_Man_t * p, Abc_Cex_t * pCexState, Abc_Cex_t * pCexImpl, Abc_Cex_t * pCexEss, int fFindAll, int fVerbose ) { Abc_Cex_t * pNew; Gia_Obj_t * pObj; int fCompl0, fCompl1; int i, k, iBit; assert( pCexState->nRegs == 0 ); // start the counter-example pNew = Abc_CexAlloc( 0, Gia_ManCiNum(p), pCexState->iFrame + 1 ); pNew->iFrame = pCexState->iFrame; pNew->iPo = pCexState->iPo; // set initial state Gia_ManCleanMark01(p); // set const0 Gia_ManConst0(p)->fMark0 = 0; Gia_ManConst0(p)->fMark1 = 1; for ( i = pCexState->iFrame; i >= 0; i-- ) { // set correct values iBit = pCexState->nPis * i; Gia_ManForEachCi( p, pObj, k ) { pObj->fMark0 = Abc_InfoHasBit(pCexState->pData, iBit+k); pObj->fMark1 = 0; if ( pCexImpl ) pObj->fMark1 |= Abc_InfoHasBit(pCexImpl->pData, iBit+k); if ( pCexEss ) pObj->fMark1 |= Abc_InfoHasBit(pCexEss->pData, iBit+k); } Gia_ManForEachAnd( p, pObj, k ) { fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj); pObj->fMark0 = fCompl0 & fCompl1; if ( pObj->fMark0 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 & Gia_ObjFanin1(pObj)->fMark1; else if ( !fCompl0 && !fCompl1 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 | Gia_ObjFanin1(pObj)->fMark1; else if ( !fCompl0 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1; else if ( !fCompl1 ) pObj->fMark1 = Gia_ObjFanin1(pObj)->fMark1; else assert( 0 ); } Gia_ManForEachCo( p, pObj, k ) pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); // move values from COs to CIs if ( i == pCexState->iFrame ) { assert( Gia_ManPo(p, pCexState->iPo)->fMark0 == 1 ); if ( fFindAll ) Bmc_CexCareBits_rec( p, Gia_ObjFanin0(Gia_ManPo(p, pCexState->iPo)) ); else Bmc_CexCareBits2_rec( p, Gia_ObjFanin0(Gia_ManPo(p, pCexState->iPo)) ); } else { Gia_ManForEachRi( p, pObj, k ) if ( Abc_InfoHasBit(pNew->pData, pNew->nPis * (i+1) + Gia_ManPiNum(p) + k) ) { if ( fFindAll ) Bmc_CexCareBits_rec( p, Gia_ObjFanin0(pObj) ); else Bmc_CexCareBits2_rec( p, Gia_ObjFanin0(pObj) ); } } // save the results Gia_ManForEachCi( p, pObj, k ) if ( pObj->fMark1 ) { pObj->fMark1 = 0; if ( pCexImpl == NULL || !Abc_InfoHasBit(pCexImpl->pData, pNew->nPis * i + k) ) Abc_InfoSetBit(pNew->pData, pNew->nPis * i + k); } } if ( pCexEss ) printf( "Minimized: " ); else printf( "Care bits: " ); Bmc_CexPrint( pNew, Gia_ManPiNum(p), fVerbose ); return pNew; } /**Function************************************************************* Synopsis [Simulates one bit to check whether it is essential.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Cex_t * Bmc_CexEssentialBitOne( Gia_Man_t * p, Abc_Cex_t * pCexState, int iBit, Abc_Cex_t * pCexPrev, int * pfEqual ) { Abc_Cex_t * pNew; Gia_Obj_t * pObj; int i, k, fCompl0, fCompl1; assert( pCexState->nRegs == 0 ); assert( iBit < pCexState->nBits ); if ( pfEqual ) *pfEqual = 0; // start the counter-example pNew = Abc_CexAllocFull( 0, Gia_ManCiNum(p), pCexState->iFrame + 1 ); pNew->iFrame = pCexState->iFrame; pNew->iPo = pCexState->iPo; // clean bit Abc_InfoXorBit( pNew->pData, iBit ); // simulate the remaining frames Gia_ManConst0(p)->fMark0 = 0; Gia_ManConst0(p)->fMark1 = 1; for ( i = iBit / pCexState->nPis; i <= pCexState->iFrame; i++ ) { Gia_ManForEachCi( p, pObj, k ) { pObj->fMark0 = Abc_InfoHasBit( pCexState->pData, i * pCexState->nPis + k ); pObj->fMark1 = Abc_InfoHasBit( pNew->pData, i * pCexState->nPis + k ); } Gia_ManForEachAnd( p, pObj, k ) { fCompl0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); fCompl1 = Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj); pObj->fMark0 = fCompl0 & fCompl1; if ( pObj->fMark0 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 & Gia_ObjFanin1(pObj)->fMark1; else if ( !fCompl0 && !fCompl1 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1 | Gia_ObjFanin1(pObj)->fMark1; else if ( !fCompl0 ) pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1; else if ( !fCompl1 ) pObj->fMark1 = Gia_ObjFanin1(pObj)->fMark1; else assert( 0 ); } Gia_ManForEachCo( p, pObj, k ) { pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); pObj->fMark1 = Gia_ObjFanin0(pObj)->fMark1; } if ( i < pCexState->iFrame ) { int fChanges = 0; int fEqual = (pCexPrev != NULL); int iBitShift = (i + 1) * pCexState->nPis + Gia_ManPiNum(p); Gia_ManForEachRi( p, pObj, k ) { if ( fEqual && pCexPrev && (int)pObj->fMark1 != Abc_InfoHasBit(pCexPrev->pData, iBitShift + k) ) fEqual = 0; if ( !pObj->fMark1 ) { fChanges = 1; Abc_InfoXorBit( pNew->pData, iBitShift + k ); } } if ( !fChanges || fEqual ) { if ( pfEqual ) *pfEqual = fEqual; Abc_CexFree( pNew ); return NULL; } } /* if ( i == 20 ) { printf( "Frame %d : ", i ); Gia_ManForEachRi( p, pObj, k ) printf( "%d", pObj->fMark1 ); printf( "\n" ); } */ } return pNew; } void Bmc_CexEssentialBitTest( Gia_Man_t * p, Abc_Cex_t * pCexState ) { Abc_Cex_t * pNew; int b; for ( b = 0; b < pCexState->nBits; b++ ) { if ( b % 100 ) continue; pNew = Bmc_CexEssentialBitOne( p, pCexState, b, NULL, NULL ); Bmc_CexPrint( pNew, Gia_ManPiNum(p), 0 ); if ( Gia_ManPo(p, pCexState->iPo)->fMark1 ) printf( "Not essential\n" ); else printf( "Essential\n" ); Abc_CexFree( pNew ); } } /**Function************************************************************* Synopsis [Computes essential bits of the CEX.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Cex_t * Bmc_CexEssentialBits( Gia_Man_t * p, Abc_Cex_t * pCexState, Abc_Cex_t * pCexCare, int fVerbose ) { Abc_Cex_t * pNew, * pTemp, * pPrev = NULL; int b, fEqual = 0, fPrevStatus = 0; // abctime clk = Abc_Clock(); assert( pCexState->nBits == pCexCare->nBits ); // start the counter-example pNew = Abc_CexAlloc( 0, Gia_ManCiNum(p), pCexState->iFrame + 1 ); pNew->iFrame = pCexState->iFrame; pNew->iPo = pCexState->iPo; // iterate through care-bits for ( b = 0; b < pCexState->nBits; b++ ) { // skip don't-care bits if ( !Abc_InfoHasBit(pCexCare->pData, b) ) continue; // skip state bits if ( b % pCexCare->nPis >= Gia_ManPiNum(p) ) { Abc_InfoSetBit( pNew->pData, b ); continue; } // check if this is an essential bit pTemp = Bmc_CexEssentialBitOne( p, pCexState, b, pPrev, &fEqual ); // pTemp = Bmc_CexEssentialBitOne( p, pCexState, b, NULL, &fEqual ); if ( pTemp == NULL ) { if ( fEqual && fPrevStatus ) Abc_InfoSetBit( pNew->pData, b ); continue; } // Bmc_CexPrint( pTemp, Gia_ManPiNum(p), fVerbose ); Abc_CexFree( pPrev ); pPrev = pTemp; // record essential bit fPrevStatus = !Gia_ManPo(p, pCexState->iPo)->fMark1; if ( !Gia_ManPo(p, pCexState->iPo)->fMark1 ) Abc_InfoSetBit( pNew->pData, b ); } Abc_CexFreeP( &pPrev ); // Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); printf( "Essentials: " ); Bmc_CexPrint( pNew, Gia_ManPiNum(p), fVerbose ); return pNew; } /**Function************************************************************* Synopsis [Computes essential bits of the CEX.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Bmc_CexTest( Gia_Man_t * p, Abc_Cex_t * pCex, int fVerbose ) { abctime clk = Abc_Clock(); Abc_Cex_t * pCexImpl = NULL; Abc_Cex_t * pCexStates = Bmc_CexInnerStates( p, pCex, &pCexImpl, fVerbose ); Abc_Cex_t * pCexCare = Bmc_CexCareBits( p, pCexStates, pCexImpl, NULL, 1, fVerbose ); Abc_Cex_t * pCexEss, * pCexMin; if ( !Bmc_CexVerify( p, pCex, pCexCare ) ) printf( "Counter-example care-set verification has failed.\n" ); pCexEss = Bmc_CexEssentialBits( p, pCexStates, pCexCare, fVerbose ); pCexMin = Bmc_CexCareBits( p, pCexStates, pCexImpl, pCexEss, 0, fVerbose ); if ( !Bmc_CexVerify( p, pCex, pCexMin ) ) printf( "Counter-example min-set verification has failed.\n" ); // Bmc_CexDumpStats( p, pCex, pCexCare, pCexEss, pCexMin, Abc_Clock() - clk ); Abc_CexFreeP( &pCexStates ); Abc_CexFreeP( &pCexImpl ); Abc_CexFreeP( &pCexCare ); Abc_CexFreeP( &pCexEss ); Abc_CexFreeP( &pCexMin ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); // Bmc_CexBuildNetworkTest( p, pCex ); // Bmc_CexPerformUnrollingTest( p, pCex ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END