/**CFile**************************************************************** FileName [giaFront.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Scalable AIG package.] Synopsis [Frontier representation.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: giaFront.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "gia.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Find the next place on the frontier.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline int Gia_ManFrontFindNext( char * pFront, int nFront, int iFront ) { assert( iFront < nFront ); for ( ; pFront[iFront]; iFront = (iFront + 1) % nFront ); assert( pFront[iFront] == 0 ); pFront[iFront] = 1; return iFront; } /**Function************************************************************* Synopsis [Transforms the frontier manager to its initial state.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManFrontTransform( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i, * pFrontToId; // mapping of nodes into frontier variables assert( p->nFront > 0 ); pFrontToId = ABC_FALLOC( int, p->nFront ); Gia_ManForEachObj( p, pObj, i ) { if ( Gia_ObjIsCo(pObj) ) { assert( pObj->Value == GIA_NONE ); pObj->iDiff0 = i - pFrontToId[Gia_ObjDiff0(pObj)]; } else if ( Gia_ObjIsAnd(pObj) ) { assert( (int)pObj->Value < p->nFront ); pObj->iDiff0 = i - pFrontToId[Gia_ObjDiff0(pObj)]; pObj->iDiff1 = i - pFrontToId[Gia_ObjDiff1(pObj)]; pFrontToId[pObj->Value] = i; } else { assert( (int)pObj->Value < p->nFront ); pFrontToId[pObj->Value] = i; } pObj->Value = 0; } ABC_FREE( pFrontToId ); } /**Function************************************************************* Synopsis [Determine the frontier.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManCrossCutSimple( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i, nCutCur = 0, nCutMax = 0; Gia_ManCreateValueRefs( p ); Gia_ManForEachObj( p, pObj, i ) { if ( pObj->Value ) nCutCur++; if ( nCutMax < nCutCur ) nCutMax = nCutCur; if ( Gia_ObjIsAnd(pObj) ) { if ( --Gia_ObjFanin0(pObj)->Value == 0 ) nCutCur--; if ( --Gia_ObjFanin1(pObj)->Value == 0 ) nCutCur--; } else if ( Gia_ObjIsCo(pObj) ) { if ( --Gia_ObjFanin0(pObj)->Value == 0 ) nCutCur--; } } // Gia_ManForEachObj( p, pObj, i ) // assert( pObj->Value == 0 ); return nCutMax; } /**Function************************************************************* Synopsis [Determine the frontier.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Gia_Man_t * Gia_ManFront( Gia_Man_t * p ) { Gia_Man_t * pNew; Gia_Obj_t * pObj, * pFanin0New, * pFanin1New, * pObjNew; char * pFront; // places used for the frontier int i, iLit, nCrossCut = 0, nCrossCutMax = 0; int nCrossCutMaxInit = Gia_ManCrossCutSimple( p ); int iFront = 0;//, clk = Abc_Clock(); // set references for all objects Gia_ManCreateValueRefs( p ); // start the new manager pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); pNew->nFront = 1 + (int)((float)1.1 * nCrossCutMaxInit); // start the frontier pFront = ABC_CALLOC( char, pNew->nFront ); // add constant node Gia_ManConst0(pNew)->Value = iFront = Gia_ManFrontFindNext( pFront, pNew->nFront, iFront ); if ( Gia_ObjValue(Gia_ManConst0(p)) == 0 ) pFront[iFront] = 0; else nCrossCut = 1; // iterate through the objects Gia_ManForEachObj1( p, pObj, i ) { if ( Gia_ObjIsCi(pObj) ) { if ( Gia_ObjValue(pObj) && nCrossCutMax < ++nCrossCut ) nCrossCutMax = nCrossCut; // create new node iLit = Gia_ManAppendCi( pNew ); pObjNew = Gia_ManObj( pNew, Abc_Lit2Var(iLit) ); assert( Gia_ObjId(pNew, pObjNew) == Gia_ObjId(p, pObj) ); pObjNew->Value = iFront = Gia_ManFrontFindNext( pFront, pNew->nFront, iFront ); // handle CIs without fanout if ( Gia_ObjValue(pObj) == 0 ) pFront[iFront] = 0; continue; } if ( Gia_ObjIsCo(pObj) ) { assert( Gia_ObjValue(pObj) == 0 ); // create new node iLit = Gia_ManAppendCo( pNew, 0 ); pObjNew = Gia_ManObj( pNew, Abc_Lit2Var(iLit) ); assert( Gia_ObjId(pNew, pObjNew) == Gia_ObjId(p, pObj) ); // get the fanin pFanin0New = Gia_ManObj( pNew, Gia_ObjFaninId0(pObj, i) ); assert( pFanin0New->Value != GIA_NONE ); pObjNew->Value = GIA_NONE; pObjNew->iDiff0 = pFanin0New->Value; pObjNew->fCompl0 = Gia_ObjFaninC0(pObj); // deref the fanin if ( --Gia_ObjFanin0(pObj)->Value == 0 ) { pFront[pFanin0New->Value] = 0; nCrossCut--; } continue; } if ( Gia_ObjValue(pObj) && nCrossCutMax < ++nCrossCut ) nCrossCutMax = nCrossCut; // create new node pObjNew = Gia_ManAppendObj( pNew ); assert( Gia_ObjId(pNew, pObjNew) == Gia_ObjId(p, pObj) ); // assign the first fanin pFanin0New = Gia_ManObj( pNew, Gia_ObjFaninId0(pObj, i) ); assert( pFanin0New->Value != GIA_NONE ); pObjNew->iDiff0 = pFanin0New->Value; pObjNew->fCompl0 = Gia_ObjFaninC0(pObj); // assign the second fanin pFanin1New = Gia_ManObj( pNew, Gia_ObjFaninId1(pObj, i) ); assert( pFanin1New->Value != GIA_NONE ); pObjNew->iDiff1 = pFanin1New->Value; pObjNew->fCompl1 = Gia_ObjFaninC1(pObj); // assign the frontier number pObjNew->Value = iFront = Gia_ManFrontFindNext( pFront, pNew->nFront, iFront ); // deref the fanins if ( --Gia_ObjFanin0(pObj)->Value == 0 ) { pFront[pFanin0New->Value] = 0; nCrossCut--; } if ( --Gia_ObjFanin1(pObj)->Value == 0 ) { pFront[pFanin1New->Value] = 0; nCrossCut--; } // handle nodes without fanout (choice nodes) if ( Gia_ObjValue(pObj) == 0 ) pFront[iFront] = 0; } assert( pNew->nObjs == p->nObjs ); assert( nCrossCut == 0 || nCrossCutMax == nCrossCutMaxInit ); for ( i = 0; i < pNew->nFront; i++ ) assert( pFront[i] == 0 ); ABC_FREE( pFront ); //printf( "Crosscut = %6d. Frontier = %6d. ", nCrossCutMaxInit, pNew->nFront ); //ABC_PRT( "Time", Abc_Clock() - clk ); Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) ); return pNew; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManFrontTest( Gia_Man_t * p ) { Gia_Man_t * pNew; pNew = Gia_ManFront( p ); Gia_ManFrontTransform( pNew ); // Gia_ManCleanValue( p ); // Gia_ManCleanValue( pNew ); if ( memcmp( pNew->pObjs, p->pObjs, sizeof(Gia_Obj_t) * p->nObjs ) ) { /* Gia_Obj_t * pObj, * pObjNew; int i; Gia_ManForEachObj( p, pObj, i ) { pObjNew = Gia_ManObj( pNew, i ); printf( "%5d %5d %5d %5d\n", pObj->iDiff0, pObjNew->iDiff0, pObj->iDiff1, pObjNew->iDiff1 ); } */ printf( "Verification failed.\n" ); } else printf( "Verification successful.\n" ); Gia_ManStop( pNew ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END