/**CFile**************************************************************** FileName [absOut.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Abstraction package.] Synopsis [Abstraction refinement outside of abstraction engines.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: absOut.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "abs.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Derive a new counter-example.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Cex_t * Gia_ManCexRemap( Gia_Man_t * p, Abc_Cex_t * pCexAbs, Vec_Int_t * vPis ) { Abc_Cex_t * pCex; int i, f, iPiNum; assert( pCexAbs->iPo == 0 ); // start the counter-example pCex = Abc_CexAlloc( Gia_ManRegNum(p), Gia_ManPiNum(p), pCexAbs->iFrame+1 ); pCex->iFrame = pCexAbs->iFrame; pCex->iPo = pCexAbs->iPo; // copy the bit data for ( f = 0; f <= pCexAbs->iFrame; f++ ) for ( i = 0; i < Vec_IntSize(vPis); i++ ) { if ( Abc_InfoHasBit( pCexAbs->pData, pCexAbs->nRegs + pCexAbs->nPis * f + i ) ) { iPiNum = Gia_ObjCioId( Gia_ManObj(p, Vec_IntEntry(vPis, i)) ); Abc_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * f + iPiNum ); } } // verify the counter example if ( !Gia_ManVerifyCex( p, pCex, 0 ) ) { Abc_Print( 1, "Gia_ManCexRemap(): Counter-example is invalid.\n" ); Abc_CexFree( pCex ); pCex = NULL; } else { Abc_Print( 1, "Counter-example verification is successful.\n" ); Abc_Print( 1, "Output %d of miter \"%s\" was asserted in frame %d. \n", pCex->iPo, p->pName, pCex->iFrame ); } return pCex; } /**Function************************************************************* Synopsis [Refines gate-level abstraction using the counter-example.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManGlaRefine( Gia_Man_t * p, Abc_Cex_t * pCex, int fMinCut, int fVerbose ) { extern void Nwk_ManDeriveMinCut( Gia_Man_t * p, int fVerbose ); int fAddOneLayer = 1; Abc_Cex_t * pCexNew = NULL; Gia_Man_t * pAbs; Aig_Man_t * pAig; Abc_Cex_t * pCare; Vec_Int_t * vPis, * vPPis; int f, i, iObjId; abctime clk = Abc_Clock(); int nOnes = 0, Counter = 0; if ( p->vGateClasses == NULL ) { Abc_Print( 1, "Gia_ManGlaRefine(): Abstraction gate map is missing.\n" ); return -1; } // derive abstraction pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); Gia_ManStop( pAbs ); pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); if ( Gia_ManPiNum(pAbs) != pCex->nPis ) { Abc_Print( 1, "Gia_ManGlaRefine(): The PI counts in GLA and in CEX do not match.\n" ); Gia_ManStop( pAbs ); return -1; } if ( !Gia_ManVerifyCex( pAbs, pCex, 0 ) ) { Abc_Print( 1, "Gia_ManGlaRefine(): The initial counter-example is invalid.\n" ); // Gia_ManStop( pAbs ); // return -1; } // else // Abc_Print( 1, "Gia_ManGlaRefine(): The initial counter-example is correct.\n" ); // get inputs Gia_ManGlaCollect( p, p->vGateClasses, &vPis, &vPPis, NULL, NULL ); assert( Vec_IntSize(vPis) + Vec_IntSize(vPPis) == Gia_ManPiNum(pAbs) ); // add missing logic if ( fAddOneLayer ) { Gia_Obj_t * pObj; // check if this is a real counter-example Gia_ObjTerSimSet0( Gia_ManConst0(pAbs) ); for ( f = 0; f <= pCex->iFrame; f++ ) { Gia_ManForEachPi( pAbs, pObj, i ) { if ( i >= Vec_IntSize(vPis) ) // PPIs Gia_ObjTerSimSetX( pObj ); else if ( Abc_InfoHasBit(pCex->pData, pCex->nRegs + pCex->nPis * f + i) ) Gia_ObjTerSimSet1( pObj ); else Gia_ObjTerSimSet0( pObj ); } Gia_ManForEachRo( pAbs, pObj, i ) { if ( f == 0 ) Gia_ObjTerSimSet0( pObj ); else Gia_ObjTerSimRo( pAbs, pObj ); } Gia_ManForEachAnd( pAbs, pObj, i ) Gia_ObjTerSimAnd( pObj ); Gia_ManForEachCo( pAbs, pObj, i ) Gia_ObjTerSimCo( pObj ); } pObj = Gia_ManPo( pAbs, 0 ); if ( Gia_ObjTerSimGet1(pObj) ) { pCexNew = Gia_ManCexRemap( p, pCex, vPis ); Abc_Print( 1, "Procedure &gla_refine found a real counter-example in frame %d.\n", pCexNew->iFrame ); } // else // Abc_Print( 1, "CEX is not real.\n" ); Gia_ManForEachObj( pAbs, pObj, i ) Gia_ObjTerSimSetC( pObj ); if ( pCexNew == NULL ) { // grow one layer Vec_IntForEachEntry( vPPis, iObjId, i ) { assert( Vec_IntEntry( p->vGateClasses, iObjId ) == 0 ); Vec_IntWriteEntry( p->vGateClasses, iObjId, 1 ); } if ( fVerbose ) { Abc_Print( 1, "Additional objects = %d. ", Vec_IntSize(vPPis) ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } } } else { // minimize the CEX pAig = Gia_ManToAigSimple( pAbs ); pCare = Saig_ManCbaFindCexCareBits( pAig, pCex, Vec_IntSize(vPis), fVerbose ); Aig_ManStop( pAig ); if ( pCare == NULL ) Abc_Print( 1, "Counter-example minimization has failed.\n" ); // add new objects to the map iObjId = -1; for ( f = 0; f <= pCare->iFrame; f++ ) for ( i = 0; i < pCare->nPis; i++ ) if ( Abc_InfoHasBit( pCare->pData, pCare->nRegs + f * pCare->nPis + i ) ) { nOnes++; assert( i >= Vec_IntSize(vPis) ); iObjId = Vec_IntEntry( vPPis, i - Vec_IntSize(vPis) ); assert( iObjId > 0 && iObjId < Gia_ManObjNum(p) ); if ( Vec_IntEntry( p->vGateClasses, iObjId ) > 0 ) continue; assert( Vec_IntEntry( p->vGateClasses, iObjId ) == 0 ); Vec_IntWriteEntry( p->vGateClasses, iObjId, 1 ); // Abc_Print( 1, "Adding object %d.\n", iObjId ); // Gia_ObjPrint( p, Gia_ManObj(p, iObjId) ); Counter++; } Abc_CexFree( pCare ); if ( fVerbose ) { Abc_Print( 1, "Essential bits = %d. Additional objects = %d. ", nOnes, Counter ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); } // consider the case of SAT if ( iObjId == -1 ) { pCexNew = Gia_ManCexRemap( p, pCex, vPis ); Abc_Print( 1, "Procedure &gla_refine found a real counter-example in frame %d.\n", pCexNew->iFrame ); } } Vec_IntFree( vPis ); Vec_IntFree( vPPis ); Gia_ManStop( pAbs ); if ( pCexNew ) { ABC_FREE( p->pCexSeq ); p->pCexSeq = pCexNew; return 0; } // extract abstraction to include min-cut if ( fMinCut ) Nwk_ManDeriveMinCut( p, fVerbose ); return -1; } /**Function************************************************************* Synopsis [Resimulates the counter-example and returns flop values.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Vec_Int_t * Gia_ManGetStateAndCheckCex( Gia_Man_t * pAig, Abc_Cex_t * p, int iFrame ) { Vec_Int_t * vInit = Vec_IntAlloc( Gia_ManRegNum(pAig) ); Gia_Obj_t * pObj, * pObjRi, * pObjRo; int RetValue, i, k, iBit = 0; assert( iFrame >= 0 && iFrame <= p->iFrame ); Gia_ManCleanMark0(pAig); Gia_ManForEachRo( pAig, pObj, i ) pObj->fMark0 = 0;//Abc_InfoHasBit(p->pData, iBit++); for ( i = 0, iBit = p->nRegs; i <= p->iFrame; i++ ) { if ( i == iFrame ) { Gia_ManForEachRo( pAig, pObjRo, k ) Vec_IntPush( vInit, pObjRo->fMark0 ); } Gia_ManForEachPi( pAig, pObj, k ) pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++); Gia_ManForEachAnd( pAig, pObj, k ) pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); Gia_ManForEachCo( pAig, pObj, k ) pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); if ( i == p->iFrame ) break; Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) pObjRo->fMark0 = pObjRi->fMark0; } assert( iBit == p->nBits ); RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; if ( RetValue != 1 ) Vec_IntFreeP( &vInit ); Gia_ManCleanMark0(pAig); return vInit; } /**Function************************************************************* Synopsis [Verify counter-example starting in the given timeframe.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManCheckCex( Gia_Man_t * pAig, Abc_Cex_t * p, int iFrame ) { Gia_Obj_t * pObj, * pObjRi, * pObjRo; int RetValue, i, k, iBit = 0; assert( iFrame >= 0 && iFrame <= p->iFrame ); Gia_ManCleanMark0(pAig); Gia_ManForEachRo( pAig, pObj, i ) pObj->fMark0 = 0;//Abc_InfoHasBit(p->pData, iBit++); for ( i = iFrame, iBit += p->nRegs + Gia_ManPiNum(pAig) * iFrame; i <= p->iFrame; i++ ) { Gia_ManForEachPi( pAig, pObj, k ) pObj->fMark0 = Abc_InfoHasBit(p->pData, iBit++); Gia_ManForEachAnd( pAig, pObj, k ) pObj->fMark0 = (Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj)) & (Gia_ObjFanin1(pObj)->fMark0 ^ Gia_ObjFaninC1(pObj)); Gia_ManForEachCo( pAig, pObj, k ) pObj->fMark0 = Gia_ObjFanin0(pObj)->fMark0 ^ Gia_ObjFaninC0(pObj); if ( i == p->iFrame ) break; Gia_ManForEachRiRo( pAig, pObjRi, pObjRo, k ) pObjRo->fMark0 = pObjRi->fMark0; } assert( iBit == p->nBits ); RetValue = Gia_ManPo(pAig, p->iPo)->fMark0; Gia_ManCleanMark0(pAig); if ( RetValue == 1 ) printf( "Shortened CEX holds for the abstraction of the fast-forwarded model.\n" ); else printf( "Shortened CEX does not hold for the abstraction of the fast-forwarded model.\n" ); } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManTransformFlops( Gia_Man_t * p, Vec_Int_t * vFlops, Vec_Int_t * vInit ) { Vec_Bit_t * vInitNew; Gia_Man_t * pNew; Gia_Obj_t * pObj; int i, iFlopId; assert( Vec_IntSize(vInit) == Vec_IntSize(vFlops) ); vInitNew = Vec_BitStart( Gia_ManRegNum(p) ); Gia_ManForEachObjVec( vFlops, p, pObj, i ) { assert( Gia_ObjIsRo(p, pObj) ); if ( Vec_IntEntry(vInit, i) == 0 ) continue; iFlopId = Gia_ObjCioId(pObj) - Gia_ManPiNum(p); assert( iFlopId >= 0 && iFlopId < Gia_ManRegNum(p) ); Vec_BitWriteEntry( vInitNew, iFlopId, 1 ); } pNew = Gia_ManDupFlip( p, Vec_BitArray(vInitNew) ); Vec_BitFree( vInitNew ); return pNew; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManNewRefine( Gia_Man_t * p, Abc_Cex_t * pCex, int iFrameStart, int iFrameExtra, int fVerbose ) { Gia_Man_t * pAbs, * pNew; Vec_Int_t * vFlops, * vInit; Vec_Int_t * vCopy; // abctime clk = Abc_Clock(); int RetValue; ABC_FREE( p->pCexSeq ); if ( p->vGateClasses == NULL ) { Abc_Print( 1, "Gia_ManNewRefine(): Abstraction gate map is missing.\n" ); return -1; } vCopy = Vec_IntDup( p->vGateClasses ); Abc_Print( 1, "Refining with %d-frame CEX, starting in frame %d, with %d extra frames.\n", pCex->iFrame, iFrameStart, iFrameExtra ); // derive abstraction pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); Gia_ManStop( pAbs ); pAbs = Gia_ManDupAbsGates( p, p->vGateClasses ); if ( Gia_ManPiNum(pAbs) != pCex->nPis ) { Abc_Print( 1, "Gia_ManNewRefine(): The PI counts in GLA and in CEX do not match.\n" ); Gia_ManStop( pAbs ); Vec_IntFree( vCopy ); return -1; } // get the state in frame iFrameStart vInit = Gia_ManGetStateAndCheckCex( pAbs, pCex, iFrameStart ); if ( vInit == NULL ) { Abc_Print( 1, "Gia_ManNewRefine(): The initial counter-example is invalid.\n" ); Gia_ManStop( pAbs ); Vec_IntFree( vCopy ); return -1; } if ( fVerbose ) Abc_Print( 1, "Gia_ManNewRefine(): The initial counter-example is correct.\n" ); // get inputs Gia_ManGlaCollect( p, p->vGateClasses, NULL, NULL, &vFlops, NULL ); // assert( Vec_IntSize(vPis) + Vec_IntSize(vPPis) == Gia_ManPiNum(pAbs) ); Gia_ManStop( pAbs ); //Vec_IntPrint( vFlops ); //Vec_IntPrint( vInit ); // transform the manager to have new init state pNew = Gia_ManTransformFlops( p, vFlops, vInit ); Vec_IntFree( vFlops ); Vec_IntFree( vInit ); // verify abstraction { Gia_Man_t * pAbs = Gia_ManDupAbsGates( pNew, p->vGateClasses ); Gia_ManCheckCex( pAbs, pCex, iFrameStart ); Gia_ManStop( pAbs ); } // transfer abstraction assert( pNew->vGateClasses == NULL ); pNew->vGateClasses = Vec_IntDup( p->vGateClasses ); // perform abstraction for the new AIG { Abs_Par_t Pars, * pPars = &Pars; Abs_ParSetDefaults( pPars ); pPars->nFramesMax = pCex->iFrame - iFrameStart + 1 + iFrameExtra; pPars->fVerbose = fVerbose; RetValue = Gia_ManPerformGla( pNew, pPars ); if ( RetValue == 0 ) // spurious SAT { Vec_IntFreeP( &pNew->vGateClasses ); pNew->vGateClasses = Vec_IntDup( vCopy ); } } // move the abstraction map Vec_IntFreeP( &p->vGateClasses ); p->vGateClasses = pNew->vGateClasses; pNew->vGateClasses = NULL; // cleanup Gia_ManStop( pNew ); Vec_IntFree( vCopy ); return -1; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END