/**CFile**************************************************************** FileName [saigTrans.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Sequential AIG package.] Synopsis [Dynamic simplication of the transition relation.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: saigTrans.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "saig.h" #include "proof/fra/fra.h" ABC_NAMESPACE_IMPL_START /* A similar approach is presented in the his paper: A. Kuehlmann. Dynamic transition relation simplification for bounded property checking. ICCAD'04, pp. 50-57. */ //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Maps a node/frame into a node of a different manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Saig_ManStartMap1( Aig_Man_t * p, int nFrames ) { Vec_Int_t * vMap; int i; assert( p->pData == NULL ); vMap = Vec_IntAlloc( Aig_ManObjNumMax(p) * nFrames ); for ( i = 0; i < vMap->nCap; i++ ) vMap->pArray[i] = -1; vMap->nSize = vMap->nCap; p->pData = vMap; } static inline void Saig_ManStopMap1( Aig_Man_t * p ) { assert( p->pData != NULL ); Vec_IntFree( (Vec_Int_t *)p->pData ); p->pData = NULL; } static inline int Saig_ManHasMap1( Aig_Man_t * p ) { return (int)(p->pData != NULL); } static inline void Saig_ManSetMap1( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, Aig_Obj_t * pNew ) { Vec_Int_t * vMap = (Vec_Int_t *)p->pData; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; assert( !Aig_IsComplement(pOld) ); assert( !Aig_IsComplement(pNew) ); Vec_IntWriteEntry( vMap, nOffset, pNew->Id ); } static inline int Saig_ManGetMap1( Aig_Man_t * p, Aig_Obj_t * pOld, int f1 ) { Vec_Int_t * vMap = (Vec_Int_t *)p->pData; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; return Vec_IntEntry( vMap, nOffset ); } /**Function************************************************************* Synopsis [Maps a node/frame into a node/frame of a different manager.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Saig_ManStartMap2( Aig_Man_t * p, int nFrames ) { Vec_Int_t * vMap; int i; assert( p->pData2 == NULL ); vMap = Vec_IntAlloc( Aig_ManObjNumMax(p) * nFrames * 2 ); for ( i = 0; i < vMap->nCap; i++ ) vMap->pArray[i] = -1; vMap->nSize = vMap->nCap; p->pData2 = vMap; } static inline void Saig_ManStopMap2( Aig_Man_t * p ) { assert( p->pData2 != NULL ); Vec_IntFree( (Vec_Int_t *)p->pData2 ); p->pData2 = NULL; } static inline int Saig_ManHasMap2( Aig_Man_t * p ) { return (int)(p->pData2 != NULL); } static inline void Saig_ManSetMap2( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, Aig_Obj_t * pNew, int f2 ) { Vec_Int_t * vMap = (Vec_Int_t *)p->pData2; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; assert( !Aig_IsComplement(pOld) ); assert( !Aig_IsComplement(pNew) ); Vec_IntWriteEntry( vMap, 2*nOffset + 0, pNew->Id ); Vec_IntWriteEntry( vMap, 2*nOffset + 1, f2 ); } static inline int Saig_ManGetMap2( Aig_Man_t * p, Aig_Obj_t * pOld, int f1, int * pf2 ) { Vec_Int_t * vMap = (Vec_Int_t *)p->pData2; int nOffset = f1 * Aig_ManObjNumMax(p) + pOld->Id; *pf2 = Vec_IntEntry( vMap, 2*nOffset + 1 ); return Vec_IntEntry( vMap, 2*nOffset ); } /**Function************************************************************* Synopsis [Create mapping for the first nFrames timeframes of pAig.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Saig_ManCreateMapping( Aig_Man_t * pAig, Aig_Man_t * pFrames, int nFrames ) { Aig_Obj_t * pObj, * pObjFrame, * pObjRepr; int i, f, iNum, iFrame; assert( pFrames->pReprs != NULL ); // mapping from nodes into their representatives // start step mapping for both orignal manager and fraig Saig_ManStartMap2( pAig, nFrames ); Saig_ManStartMap2( pFrames, 1 ); // for each object in each frame for ( f = 0; f < nFrames; f++ ) Aig_ManForEachObj( pAig, pObj, i ) { // get the frame object iNum = Saig_ManGetMap1( pAig, pObj, f ); pObjFrame = Aig_ManObj( pFrames, iNum ); // if the node has no prototype, map it into itself if ( pObjFrame == NULL ) { Saig_ManSetMap2( pAig, pObj, f, pObj, f ); continue; } // get the representative object pObjRepr = Aig_ObjRepr( pFrames, pObjFrame ); if ( pObjRepr == NULL ) pObjRepr = pObjFrame; // check if this is the first time this object is reached if ( Saig_ManGetMap2( pFrames, pObjRepr, 0, &iFrame ) == -1 ) Saig_ManSetMap2( pFrames, pObjRepr, 0, pObj, f ); // set the map for the main object iNum = Saig_ManGetMap2( pFrames, pObjRepr, 0, &iFrame ); Saig_ManSetMap2( pAig, pObj, f, Aig_ManObj(pAig, iNum), iFrame ); } Saig_ManStopMap2( pFrames ); assert( Saig_ManHasMap2(pAig) ); } /**Function************************************************************* Synopsis [Unroll without initialization.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Man_t * Saig_ManFramesNonInitial( Aig_Man_t * pAig, int nFrames ) { Aig_Man_t * pFrames; Aig_Obj_t * pObj, * pObjLi, * pObjLo; int i, f; assert( Saig_ManRegNum(pAig) > 0 ); // start node map Saig_ManStartMap1( pAig, nFrames ); // start the new manager pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFrames ); // map the constant node Aig_ManConst1(pAig)->pData = Aig_ManConst1( pFrames ); // create variables for register outputs Saig_ManForEachLo( pAig, pObj, i ) pObj->pData = Aig_ObjCreateCi( pFrames ); // add timeframes for ( f = 0; f < nFrames; f++ ) { // create PI nodes for this frame Saig_ManForEachPi( pAig, pObj, i ) pObj->pData = Aig_ObjCreateCi( pFrames ); // add internal nodes of this frame Aig_ManForEachNode( pAig, pObj, i ) pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); // create POs for this frame Saig_ManForEachPo( pAig, pObj, i ) pObj->pData = Aig_ObjCreateCo( pFrames, Aig_ObjChild0Copy(pObj) ); // save register inputs Saig_ManForEachLi( pAig, pObj, i ) pObj->pData = Aig_ObjChild0Copy(pObj); // save the mapping Aig_ManForEachObj( pAig, pObj, i ) { assert( pObj->pData != NULL ); Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // quit if the last frame if ( f == nFrames - 1 ) break; // transfer to register outputs Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) pObjLo->pData = pObjLi->pData; } // remember register outputs Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) Aig_ObjCreateCo( pFrames, (Aig_Obj_t *)pObjLi->pData ); Aig_ManCleanup( pFrames ); return pFrames; } /**Function************************************************************* Synopsis [Unroll with initialization and mapping.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Man_t * Saig_ManFramesInitialMapped( Aig_Man_t * pAig, int nFrames, int nFramesMax, int fInit ) { Aig_Man_t * pFrames; Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pRepr; int i, f, iNum1, iNum2, iFrame2; assert( nFrames <= nFramesMax ); assert( Saig_ManRegNum(pAig) > 0 ); // start node map Saig_ManStartMap1( pAig, nFramesMax ); // start the new manager pFrames = Aig_ManStart( Aig_ManNodeNum(pAig) * nFramesMax ); // create variables for register outputs if ( fInit ) { Saig_ManForEachLo( pAig, pObj, i ) { pObj->pData = Aig_ManConst0( pFrames ); Saig_ManSetMap1( pAig, pObj, 0, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } } else { // create PIs first for ( f = 0; f < nFramesMax; f++ ) Saig_ManForEachPi( pAig, pObj, i ) Aig_ObjCreateCi( pFrames ); // create registers second Saig_ManForEachLo( pAig, pObj, i ) { pObj->pData = Aig_ObjCreateCi( pFrames ); Saig_ManSetMap1( pAig, pObj, 0, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } } // add timeframes for ( f = 0; f < nFramesMax; f++ ) { // map the constant node pObj = Aig_ManConst1(pAig); pObj->pData = Aig_ManConst1( pFrames ); Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); // create PI nodes for this frame Saig_ManForEachPi( pAig, pObj, i ) { if ( fInit ) pObj->pData = Aig_ObjCreateCi( pFrames ); else pObj->pData = Aig_ManCi( pFrames, f * Saig_ManPiNum(pAig) + i ); Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // add internal nodes of this frame Aig_ManForEachNode( pAig, pObj, i ) { pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); if ( !Saig_ManHasMap2(pAig) ) continue; if ( f < nFrames ) { // get the mapping for this node iNum2 = Saig_ManGetMap2( pAig, pObj, f, &iFrame2 ); } else { // get the mapping for this node iNum2 = Saig_ManGetMap2( pAig, pObj, nFrames-1, &iFrame2 ); iFrame2 += f - (nFrames-1); } assert( iNum2 != -1 ); assert( f >= iFrame2 ); // get the corresponding frames node iNum1 = Saig_ManGetMap1( pAig, Aig_ManObj(pAig, iNum2), iFrame2 ); pRepr = Aig_ManObj( pFrames, iNum1 ); // compare the phases of these nodes pObj->pData = Aig_NotCond( pRepr, pRepr->fPhase ^ Aig_ObjPhaseReal((Aig_Obj_t *)pObj->pData) ); } // create POs for this frame Saig_ManForEachPo( pAig, pObj, i ) { pObj->pData = Aig_ObjCreateCo( pFrames, Aig_ObjChild0Copy(pObj) ); Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // save register inputs Saig_ManForEachLi( pAig, pObj, i ) { pObj->pData = Aig_ObjChild0Copy(pObj); Saig_ManSetMap1( pAig, pObj, f, Aig_Regular((Aig_Obj_t *)pObj->pData) ); } // quit if the last frame if ( f == nFramesMax - 1 ) break; // transfer to register outputs Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) { pObjLo->pData = pObjLi->pData; if ( !fInit ) Saig_ManSetMap1( pAig, pObjLo, f+1, Aig_Regular((Aig_Obj_t *)pObjLo->pData) ); } } if ( !fInit ) { // create registers Saig_ManForEachLiLo( pAig, pObjLi, pObjLo, i ) Aig_ObjCreateCo( pFrames, (Aig_Obj_t *)pObjLi->pData ); // set register number Aig_ManSetRegNum( pFrames, pAig->nRegs ); } Aig_ManCleanup( pFrames ); Saig_ManStopMap1( pAig ); return pFrames; } /**Function************************************************************* Synopsis [Implements dynamic simplification.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Aig_Man_t * Saig_ManTimeframeSimplify( Aig_Man_t * pAig, int nFrames, int nFramesMax, int fInit, int fVerbose ) { // extern Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax, int fProve ); Aig_Man_t * pFrames, * pFraig, * pRes1, * pRes2; abctime clk; // create uninitialized timeframes with map1 pFrames = Saig_ManFramesNonInitial( pAig, nFrames ); // perform fraiging for the unrolled timeframes clk = Abc_Clock(); pFraig = Fra_FraigEquivence( pFrames, 1000, 0 ); // report the results if ( fVerbose ) { Aig_ManPrintStats( pFrames ); Aig_ManPrintStats( pFraig ); ABC_PRT( "Fraiging", Abc_Clock() - clk ); } Aig_ManStop( pFraig ); assert( pFrames->pReprs != NULL ); // create AIG with map2 Saig_ManCreateMapping( pAig, pFrames, nFrames ); Aig_ManStop( pFrames ); Saig_ManStopMap1( pAig ); // create reduced initialized timeframes clk = Abc_Clock(); pRes2 = Saig_ManFramesInitialMapped( pAig, nFrames, nFramesMax, fInit ); ABC_PRT( "Mapped", Abc_Clock() - clk ); // free mapping Saig_ManStopMap2( pAig ); clk = Abc_Clock(); pRes1 = Saig_ManFramesInitialMapped( pAig, nFrames, nFramesMax, fInit ); ABC_PRT( "Normal", Abc_Clock() - clk ); // report the results if ( fVerbose ) { Aig_ManPrintStats( pRes1 ); Aig_ManPrintStats( pRes2 ); } Aig_ManStop( pRes1 ); assert( !Saig_ManHasMap1(pAig) ); assert( !Saig_ManHasMap2(pAig) ); return pRes2; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END