| /**CFile**************************************************************** |
| |
| FileName [giaScl.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Scalable AIG package.] |
| |
| Synopsis [Sequential cleanup.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: giaScl.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "gia.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Marks unreachable internal nodes and returns their number.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Gia_ManCombMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj ) |
| { |
| if ( pObj == NULL ) |
| return 0; |
| if ( !pObj->fMark0 ) |
| return 0; |
| pObj->fMark0 = 0; |
| assert( Gia_ObjIsAnd(pObj) ); |
| assert( !Gia_ObjIsBuf(pObj) ); |
| return 1 + Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) ) |
| + Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin1(pObj) ) |
| + (p->pNexts ? Gia_ManCombMarkUsed_rec( p, Gia_ObjNextObj(p, Gia_ObjId(p, pObj)) ) : 0) |
| + (p->pSibls ? Gia_ManCombMarkUsed_rec( p, Gia_ObjSiblObj(p, Gia_ObjId(p, pObj)) ) : 0) |
| + (p->pMuxes ? Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin2(p, pObj) ) : 0); |
| } |
| int Gia_ManCombMarkUsed( Gia_Man_t * p ) |
| { |
| Gia_Obj_t * pObj; |
| int i, nNodes = 0; |
| Gia_ManForEachObj( p, pObj, i ) |
| pObj->fMark0 = Gia_ObjIsAnd(pObj) && !Gia_ObjIsBuf(pObj); |
| Gia_ManForEachBuf( p, pObj, i ) |
| nNodes += Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) ); |
| Gia_ManForEachCo( p, pObj, i ) |
| nNodes += Gia_ManCombMarkUsed_rec( p, Gia_ObjFanin0(pObj) ); |
| return nNodes; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs combinational cleanup.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManCleanup( Gia_Man_t * p ) |
| { |
| Gia_ManCombMarkUsed( p ); |
| return Gia_ManDupMarked( p ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Skip the first outputs during cleanup.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManCleanupOutputs( Gia_Man_t * p, int nOutputs ) |
| { |
| Gia_Obj_t * pObj; |
| int i; |
| assert( Gia_ManRegNum(p) == 0 ); |
| assert( nOutputs < Gia_ManCoNum(p) ); |
| Gia_ManCombMarkUsed( p ); |
| Gia_ManForEachCo( p, pObj, i ) |
| if ( i < nOutputs ) |
| pObj->fMark0 = 1; |
| else |
| break; |
| return Gia_ManDupMarked( p ); |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Marks CIs/COs/ANDs unreachable from POs.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Gia_ManSeqMarkUsed_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vRoots ) |
| { |
| if ( !pObj->fMark0 ) |
| return 0; |
| pObj->fMark0 = 0; |
| if ( Gia_ObjIsCo(pObj) ) |
| return Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ); |
| if ( Gia_ObjIsRo(p, pObj) ) |
| { |
| Vec_IntPush( vRoots, Gia_ObjId(p, Gia_ObjRoToRi(p, pObj)) ); |
| return 0; |
| } |
| assert( Gia_ObjIsAnd(pObj) ); |
| return 1 + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin0(pObj), vRoots ) |
| + Gia_ManSeqMarkUsed_rec( p, Gia_ObjFanin1(pObj), vRoots ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Marks CIs/COs/ANDs unreachable from POs.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Gia_ManSeqMarkUsed( Gia_Man_t * p ) |
| { |
| Vec_Int_t * vRoots; |
| Gia_Obj_t * pObj; |
| int i, nNodes = 0; |
| Gia_ManSetMark0( p ); |
| Gia_ManConst0(p)->fMark0 = 0; |
| Gia_ManForEachPi( p, pObj, i ) |
| pObj->fMark0 = 0; |
| vRoots = Gia_ManCollectPoIds( p ); |
| Gia_ManForEachObjVec( vRoots, p, pObj, i ) |
| nNodes += Gia_ManSeqMarkUsed_rec( p, pObj, vRoots ); |
| Vec_IntFree( vRoots ); |
| return nNodes; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs sequential cleanup.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManSeqCleanup( Gia_Man_t * p ) |
| { |
| Gia_ManSeqMarkUsed( p ); |
| return Gia_ManDupMarked( p ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Find representatives due to identical fanins.] |
| |
| Description [Returns the old manager if there is no changes.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManReduceEquiv( Gia_Man_t * p, int fVerbose ) |
| { |
| Gia_Man_t * pNew; |
| Gia_Obj_t * pObjRi, * pObjRo; |
| unsigned * pCi2Lit, * pMaps; |
| int i, iLit, nFanins = 1, Counter0 = 0, Counter = 0; |
| Gia_ManForEachRi( p, pObjRi, i ) |
| Gia_ObjFanin0(pObjRi)->Value = 0; |
| Gia_ManForEachRi( p, pObjRi, i ) |
| if ( Gia_ObjFanin0(pObjRi)->Value == 0 ) |
| Gia_ObjFanin0(pObjRi)->Value = 2*nFanins++; |
| pCi2Lit = ABC_FALLOC( unsigned, Gia_ManCiNum(p) ); |
| pMaps = ABC_FALLOC( unsigned, 2 * nFanins ); |
| Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) |
| { |
| iLit = Gia_ObjFanin0Copy( pObjRi ); |
| if ( Gia_ObjFaninId0p(p, pObjRi) == 0 && Gia_ObjFaninC0(pObjRi) == 0 ) // const 0 |
| pCi2Lit[Gia_ManPiNum(p)+i] = 0, Counter0++; |
| else if ( ~pMaps[iLit] ) // in this case, ID(pObj) > ID(pRepr) |
| pCi2Lit[Gia_ManPiNum(p)+i] = pMaps[iLit], Counter++; |
| else |
| pMaps[iLit] = Abc_Var2Lit( Gia_ObjId(p, pObjRo), 0 ); |
| } |
| /* |
| Gia_ManForEachCi( p, pObjRo, i ) |
| { |
| if ( ~pCi2Lit[i] ) |
| { |
| Gia_Obj_t * pObj0 = Gia_ObjRoToRi(p, pObjRo); |
| Gia_Obj_t * pObj1 = Gia_ObjRoToRi(p, Gia_ManObj(p, pCi2Lit[i])); |
| Gia_Obj_t * pFan0 = Gia_ObjChild0( p, Gia_ObjRoToRi(p, pObjRo) ); |
| Gia_Obj_t * pFan1 = Gia_ObjChild0( p, Gia_ObjRoToRi(p, Gia_ManObj(p, pCi2Lit[i])) ); |
| assert( pFan0 == pFan1 ); |
| } |
| } |
| */ |
| // if ( fVerbose ) |
| // printf( "ReduceEquiv detected %d constant regs and %d equivalent regs.\n", Counter0, Counter ); |
| ABC_FREE( pMaps ); |
| if ( Counter0 || Counter ) |
| pNew = Gia_ManDupDfsCiMap( p, (int *)pCi2Lit, NULL ); |
| else |
| pNew = p; |
| ABC_FREE( pCi2Lit ); |
| return pNew; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs sequential cleanup.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Gia_Man_t * Gia_ManSeqStructSweep( Gia_Man_t * p, int fConst, int fEquiv, int fVerbose ) |
| { |
| Gia_Man_t * pTemp; |
| if ( Gia_ManRegNum(p) == 0 ) |
| return Gia_ManCleanup( p ); |
| if ( fVerbose ) |
| printf( "Performing sequential cleanup.\n" ); |
| p = Gia_ManSeqCleanup( pTemp = p ); |
| if ( fVerbose ) |
| Gia_ManReportImprovement( pTemp, p ); |
| if ( fConst && Gia_ManRegNum(p) ) |
| { |
| p = Gia_ManReduceConst( pTemp = p, fVerbose ); |
| if ( fVerbose ) |
| Gia_ManReportImprovement( pTemp, p ); |
| Gia_ManStop( pTemp ); |
| } |
| if ( fVerbose && fEquiv ) |
| printf( "Merging combinationally equivalent flops.\n" ); |
| if ( fEquiv ) |
| while ( 1 ) |
| { |
| p = Gia_ManSeqCleanup( pTemp = p ); |
| if ( fVerbose ) |
| Gia_ManReportImprovement( pTemp, p ); |
| Gia_ManStop( pTemp ); |
| if ( Gia_ManRegNum(p) == 0 ) |
| break; |
| p = Gia_ManReduceEquiv( pTemp = p, fVerbose ); |
| if ( p == pTemp ) |
| break; |
| Gia_ManStop( pTemp ); |
| } |
| return p; |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |