summaryrefslogtreecommitdiffstats
path: root/src/aig/saig
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2008-04-30 08:01:00 -0700
committerAlan Mishchenko <alanmi@berkeley.edu>2008-04-30 08:01:00 -0700
commitde81a1a1fb5d2cfff636a237a0a7008dcf196bcd (patch)
tree0ae940cc977896662e60a9050fe743ba5cd7b438 /src/aig/saig
parent2b98b81837011f26d130ad0f44d4bc7b298f9cd7 (diff)
downloadabc-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.make4
-rw-r--r--src/aig/saig/saig.h15
-rw-r--r--src/aig/saig/saigRetFwd.c242
-rw-r--r--src/aig/saig/saigRetMin.c10
-rw-r--r--src/aig/saig/saigScl.c74
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 ///
+////////////////////////////////////////////////////////////////////////
+
+