diff options
author | Alan Mishchenko <alanmi@berkeley.edu> | 2008-04-30 08:01:00 -0700 |
---|---|---|
committer | Alan Mishchenko <alanmi@berkeley.edu> | 2008-04-30 08:01:00 -0700 |
commit | de81a1a1fb5d2cfff636a237a0a7008dcf196bcd (patch) | |
tree | 0ae940cc977896662e60a9050fe743ba5cd7b438 /src/aig/saig | |
parent | 2b98b81837011f26d130ad0f44d4bc7b298f9cd7 (diff) | |
download | abc-de81a1a1fb5d2cfff636a237a0a7008dcf196bcd.tar.gz abc-de81a1a1fb5d2cfff636a237a0a7008dcf196bcd.tar.bz2 abc-de81a1a1fb5d2cfff636a237a0a7008dcf196bcd.zip |
Version abc80430
Diffstat (limited to 'src/aig/saig')
-rw-r--r-- | src/aig/saig/module.make | 4 | ||||
-rw-r--r-- | src/aig/saig/saig.h | 15 | ||||
-rw-r--r-- | src/aig/saig/saigRetFwd.c | 242 | ||||
-rw-r--r-- | src/aig/saig/saigRetMin.c | 10 | ||||
-rw-r--r-- | src/aig/saig/saigScl.c | 74 |
5 files changed, 338 insertions, 7 deletions
diff --git a/src/aig/saig/module.make b/src/aig/saig/module.make index 3902ce70..7de3ccdc 100644 --- a/src/aig/saig/module.make +++ b/src/aig/saig/module.make @@ -1,3 +1,5 @@ SRC += src/aig/saig/saig_.c \ src/aig/saig/saigPhase.c \ - src/aig/saig/saigRetMin.c + src/aig/saig/saigRetFwd.c \ + src/aig/saig/saigRetMin.c \ + src/aig/saig/saigScl.c diff --git a/src/aig/saig/saig.h b/src/aig/saig/saig.h index ce09fd32..e399b8bb 100644 --- a/src/aig/saig/saig.h +++ b/src/aig/saig/saig.h @@ -49,6 +49,11 @@ static inline int Saig_ManRegNum( Aig_Man_t * p ) { return p->n static inline Aig_Obj_t * Saig_ManLo( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPis, Saig_ManPiNum(p)+i); } static inline Aig_Obj_t * Saig_ManLi( Aig_Man_t * p, int i ) { return (Aig_Obj_t *)Vec_PtrEntry(p->vPos, Saig_ManPoNum(p)+i); } +static inline int Saig_ObjIsPi( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjIsPi(pObj) && Aig_ObjPioNum(pObj) < Saig_ManPiNum(p); } +static inline int Saig_ObjIsPo( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjIsPo(pObj) && Aig_ObjPioNum(pObj) < Saig_ManPoNum(p); } +static inline int Saig_ObjIsLo( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjIsPi(pObj) && Aig_ObjPioNum(pObj) >= Saig_ManPiNum(p); } +static inline int Saig_ObjIsLi( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjIsPo(pObj) && Aig_ObjPioNum(pObj) >= Saig_ManPoNum(p); } + // iterator over the primary inputs/outputs #define Saig_ManForEachPi( p, pObj, i ) \ Vec_PtrForEachEntryStop( p->vPis, pObj, i, Saig_ManPiNum(p) ) @@ -69,7 +74,15 @@ static inline Aig_Obj_t * Saig_ManLi( Aig_Man_t * p, int i ) { return (Aig //////////////////////////////////////////////////////////////////////// /*=== saigPhase.c ==========================================================*/ - +extern Aig_Man_t * Saig_ManPhaseAbstract( Aig_Man_t * p, Vec_Int_t * vInits, int nFrames, int fIgnore, int fPrint, int fVerbose ); +/*=== saigRetFwd.c ==========================================================*/ +extern Aig_Man_t * Saig_ManRetimeForward( Aig_Man_t * p, int nMaxIters, int fVerbose ); +/*=== saigRetMin.c ==========================================================*/ +extern Aig_Man_t * Saig_ManRetimeDupForward( Aig_Man_t * p, Vec_Ptr_t * vCut ); +extern Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ); +/*=== saigScl.c ==========================================================*/ +extern void Saig_ManReportUselessRegisters( Aig_Man_t * pAig ); + #ifdef __cplusplus } #endif diff --git a/src/aig/saig/saigRetFwd.c b/src/aig/saig/saigRetFwd.c new file mode 100644 index 00000000..b6321da6 --- /dev/null +++ b/src/aig/saig/saigRetFwd.c @@ -0,0 +1,242 @@ +/**CFile**************************************************************** + + FileName [saigRetFwd.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Most-forward retiming.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigRetFwd.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +static inline Aig_Obj_t * Aig_ObjFanoutStatic( Aig_Obj_t * pObj, int i ) { return ((Aig_Obj_t **)pObj->pData)[i]; } +static inline void Aig_ObjSetFanoutStatic( Aig_Obj_t * pObj, Aig_Obj_t * pFan ) { ((Aig_Obj_t **)pObj->pData)[pObj->nRefs++] = pFan; } + +#define Aig_ObjForEachFanoutStatic( pObj, pFan, i ) \ + for ( i = 0; (i < (int)(pObj)->nRefs) && ((pFan) = Aig_ObjFanoutStatic(pObj, i)); i++ ) + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Allocate static fanout for all nodes in the AIG manager.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Obj_t ** Aig_ManStaticFanoutStart( Aig_Man_t * p ) +{ + Aig_Obj_t ** ppFanouts, * pObj; + int i, nFanouts, nFanoutsAlloc; + // allocate fanouts + nFanoutsAlloc = 2 * Aig_ManObjNumMax(p) - Aig_ManPiNum(p) - Aig_ManPoNum(p); + ppFanouts = ALLOC( Aig_Obj_t *, nFanoutsAlloc ); + // mark up storage + nFanouts = 0; + Aig_ManForEachObj( p, pObj, i ) + { + pObj->pData = ppFanouts + nFanouts; + nFanouts += pObj->nRefs; + pObj->nRefs = 0; + } + assert( nFanouts < nFanoutsAlloc ); + // add fanouts + Aig_ManForEachObj( p, pObj, i ) + { + if ( Aig_ObjChild0(pObj) ) + Aig_ObjSetFanoutStatic( Aig_ObjFanin0(pObj), pObj ); + if ( Aig_ObjChild1(pObj) ) + Aig_ObjSetFanoutStatic( Aig_ObjFanin1(pObj), pObj ); + } + return ppFanouts; +} + +/**Function************************************************************* + + Synopsis [Marks the objects reachable from the given object.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Aig_ManMarkAutonomous_rec( Aig_Man_t * p, Aig_Obj_t * pObj ) +{ + Aig_Obj_t * pFanout; + int i; + if ( Aig_ObjIsTravIdCurrent(p, pObj) ) + return; + Aig_ObjSetTravIdCurrent(p, pObj); + Aig_ObjForEachFanoutStatic( pObj, pFanout, i ) + Aig_ManMarkAutonomous_rec( p, pFanout ); +} + +/**Function************************************************************* + + Synopsis [Marks with current trav ID nodes reachable from Const1 and PIs.] + + Description [Returns the number of unreachable registers.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManMarkAutonomous( Aig_Man_t * p ) +{ + Aig_Obj_t ** ppFanouts; + Aig_Obj_t * pObj, * pObjLi, * pObjLo; + int i; + // temporarily connect register outputs to register inputs + Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) + { + pObjLo->pFanin0 = pObjLi; + pObjLi->nRefs = 1; + } + // mark nodes reachable from Const1 and PIs + Aig_ManIncrementTravId( p ); + ppFanouts = Aig_ManStaticFanoutStart( p ); + Aig_ManMarkAutonomous_rec( p, Aig_ManConst1(p) ); + Saig_ManForEachPi( p, pObj, i ) + Aig_ManMarkAutonomous_rec( p, pObj ); + free( ppFanouts ); + // disconnect LIs/LOs and label unreachable registers + Saig_ManForEachLiLo( p, pObjLi, pObjLo, i ) + { + assert( pObjLo->pFanin0 && pObjLi->nRefs == 1 ); + pObjLo->pFanin0 = NULL; + pObjLi->nRefs = 0; + } +} + +/**Function************************************************************* + + Synopsis [Derives the cut for forward retiming.] + + Description [Assumes topological ordering of the nodes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManRetimeForwardOne( Aig_Man_t * p, int * pnRegFixed, int * pnRegMoves ) +{ + Aig_Man_t * pNew; + Vec_Ptr_t * vCut; + Aig_Obj_t * pObj, * pFanin; + int i; + // mark the retimable nodes + Saig_ManMarkAutonomous( p ); + // mark the retimable registers with the fresh trav ID + Aig_ManIncrementTravId( p ); + *pnRegFixed = 0; + Saig_ManForEachLo( p, pObj, i ) + if ( Aig_ObjIsTravIdPrevious(p, pObj) ) + Aig_ObjSetTravIdCurrent(p, pObj); + else + (*pnRegFixed)++; + // mark all the nodes that can be retimed forward + *pnRegMoves = 0; + Aig_ManForEachNode( p, pObj, i ) + if ( Aig_ObjIsTravIdCurrent(p, Aig_ObjFanin0(pObj)) && Aig_ObjIsTravIdCurrent(p, Aig_ObjFanin1(pObj)) ) + { + Aig_ObjSetTravIdCurrent(p, pObj); + (*pnRegMoves)++; + } + // mark the remaining registers + Saig_ManForEachLo( p, pObj, i ) + Aig_ObjSetTravIdCurrent(p, pObj); + // find the cut (all such marked objects that fanout into unmarked nodes) + vCut = Vec_PtrAlloc( 1000 ); + Aig_ManIncrementTravId( p ); + Aig_ManForEachObj( p, pObj, i ) + { + if ( Aig_ObjIsTravIdPrevious(p, pObj) ) + continue; + pFanin = Aig_ObjFanin0(pObj); + if ( pFanin && Aig_ObjIsTravIdPrevious(p, pFanin) ) + { + Vec_PtrPush( vCut, pFanin ); + Aig_ObjSetTravIdCurrent( p, pFanin ); + } + pFanin = Aig_ObjFanin1(pObj); + if ( pFanin && Aig_ObjIsTravIdPrevious(p, pFanin) ) + { + Vec_PtrPush( vCut, pFanin ); + Aig_ObjSetTravIdCurrent( p, pFanin ); + } + } + // finally derive the new manager + pNew = Saig_ManRetimeDupForward( p, vCut ); + Vec_PtrFree( vCut ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [Derives the cut for forward retiming.] + + Description [Assumes topological ordering of the nodes.] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Aig_Man_t * Saig_ManRetimeForward( Aig_Man_t * p, int nMaxIters, int fVerbose ) +{ + Aig_Man_t * pNew, * pTemp; + int i, clk, nRegFixed, nRegMoves = 1; + pNew = p; + for ( i = 0; i < nMaxIters && nRegMoves > 0; i++ ) + { + clk = clock(); + pNew = Saig_ManRetimeForwardOne( pTemp = pNew, &nRegFixed, &nRegMoves ); + if ( fVerbose ) + { + printf( "%2d : And = %6d. Reg = %5d. Unret = %5d. Move = %6d. ", + i + 1, Aig_ManNodeNum(pTemp), Aig_ManRegNum(pTemp), nRegFixed, nRegMoves ); + PRT( "Time", clock() - clk ); + } + if ( pTemp != p ) + Aig_ManStop( pTemp ); + } + clk = clock(); + pNew = Aig_ManReduceLaches( pNew, fVerbose ); + if ( fVerbose ) + { + PRT( "Register sharing time", clock() - clk ); + } + return pNew; +} + + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/aig/saig/saigRetMin.c b/src/aig/saig/saigRetMin.c index c53d6d6b..324d8867 100644 --- a/src/aig/saig/saigRetMin.c +++ b/src/aig/saig/saigRetMin.c @@ -617,16 +617,16 @@ Aig_Man_t * Saig_ManRetimeMinAreaBackward( Aig_Man_t * pNew, int fVerbose ) SeeAlso [] ***********************************************************************/ -Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ) +Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int nMaxIters, int fForwardOnly, int fBackwardOnly, int fInitial, int fVerbose ) { Vec_Ptr_t * vCut; Aig_Man_t * pNew, * pTemp, * pCopy; - int fChanges; + int i, fChanges; pNew = Aig_ManDup( p ); // perform several iterations of forward retiming fChanges = 0; if ( !fBackwardOnly ) - while ( 1 ) + for ( i = 0; i < nMaxIters; i++ ) { vCut = Nwk_ManDeriveRetimingCut( pNew, 1, fVerbose ); if ( Vec_PtrSize(vCut) >= Aig_ManRegNum(pNew) ) @@ -646,7 +646,7 @@ Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int fForwardOnly, int fBackwar // perform several iterations of backward retiming fChanges = 0; if ( !fForwardOnly && !fInitial ) - while ( 1 ) + for ( i = 0; i < nMaxIters; i++ ) { vCut = Nwk_ManDeriveRetimingCut( pNew, 0, fVerbose ); if ( Vec_PtrSize(vCut) >= Aig_ManRegNum(pNew) ) @@ -664,7 +664,7 @@ Aig_Man_t * Saig_ManRetimeMinArea( Aig_Man_t * p, int fForwardOnly, int fBackwar fChanges = 1; } else if ( !fForwardOnly && fInitial ) - while ( 1 ) + for ( i = 0; i < nMaxIters; i++ ) { pCopy = Aig_ManDup( pNew ); pTemp = Saig_ManRetimeMinAreaBackward( pCopy, fVerbose ); diff --git a/src/aig/saig/saigScl.c b/src/aig/saig/saigScl.c new file mode 100644 index 00000000..b747eff9 --- /dev/null +++ b/src/aig/saig/saigScl.c @@ -0,0 +1,74 @@ +/**CFile**************************************************************** + + FileName [saigScl.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Sequential AIG package.] + + Synopsis [Sequential cleanup.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: saigScl.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "saig.h" + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [Report registers useless for SEC.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Saig_ManReportUselessRegisters( Aig_Man_t * pAig ) +{ + Aig_Obj_t * pObj, * pDriver; + int i, Counter1, Counter2; + // set PIO numbers + Aig_ManSetPioNumbers( pAig ); + // check how many POs are driven by a register whose ref count is 1 + Counter1 = 0; + Saig_ManForEachPo( pAig, pObj, i ) + { + pDriver = Aig_ObjFanin0(pObj); + if ( Saig_ObjIsLo(pAig, pDriver) && Aig_ObjRefs(pDriver) == 1 ) + Counter1++; + } + // check how many PIs have ref count 1 and drive a register + Counter2 = 0; + Saig_ManForEachLi( pAig, pObj, i ) + { + pDriver = Aig_ObjFanin0(pObj); + if ( Saig_ObjIsPi(pAig, pDriver) && Aig_ObjRefs(pDriver) == 1 ) + Counter2++; + } + if ( Counter1 ) + printf( "Network has %d (out of %d) registers driving POs.\n", Counter1, Saig_ManRegNum(pAig) ); + if ( Counter2 ) + printf( "Network has %d (out of %d) registers driven by PIs.\n", Counter2, Saig_ManRegNum(pAig) ); +} + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + |