summaryrefslogtreecommitdiffstats
path: root/src/base/acb/acbUtil.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/acb/acbUtil.c')
-rw-r--r--src/base/acb/acbUtil.c340
1 files changed, 340 insertions, 0 deletions
diff --git a/src/base/acb/acbUtil.c b/src/base/acb/acbUtil.c
new file mode 100644
index 00000000..4dcae435
--- /dev/null
+++ b/src/base/acb/acbUtil.c
@@ -0,0 +1,340 @@
+/**CFile****************************************************************
+
+ FileName [acbUtil.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Hierarchical word-level netlist.]
+
+ Synopsis [Various utilities.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - July 21, 2015.]
+
+ Revision [$Id: acbUtil.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "acb.h"
+#include "base/abc/abc.h"
+
+ABC_NAMESPACE_IMPL_START
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFINITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acb_NtkCreateFanout( Acb_Ntk_t * p )
+{
+ int k, iObj, iFanin, * pFanins;
+ Vec_WecInit( &p->vFanouts, Acb_NtkObjNumMax(p) );
+ Acb_NtkForEachObj( p, iObj )
+ Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
+ Vec_IntPush( Vec_WecEntry(&p->vFanouts, iFanin), iObj );
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Acb_ObjCollectTfi_rec( Acb_Ntk_t * p, int iObj, int fTerm )
+{
+ int * pFanin, iFanin, i;
+ if ( Acb_ObjSetTravIdCur(p, iObj) )
+ return;
+ if ( !fTerm && Acb_ObjIsCi(p, iObj) )
+ return;
+ Acb_ObjForEachFaninFast( p, iObj, pFanin, iFanin, i )
+ Acb_ObjCollectTfi_rec( p, iFanin, fTerm );
+ Vec_IntPush( &p->vArray0, iObj );
+}
+Vec_Int_t * Acb_ObjCollectTfi( Acb_Ntk_t * p, int iObj, int fTerm )
+{
+ Vec_IntClear( &p->vArray0 );
+ Acb_NtkIncTravId( p );
+ Acb_ObjCollectTfi_rec( p, iObj, fTerm );
+ return &p->vArray0;
+}
+
+void Acb_ObjCollectTfo_rec( Acb_Ntk_t * p, int iObj, int fTerm )
+{
+ int iFanout, i;
+ if ( Acb_ObjSetTravIdCur(p, iObj) )
+ return;
+ if ( !fTerm && Acb_ObjIsCo(p, iObj) )
+ return;
+ Acb_ObjForEachFanout( p, iObj, iFanout, i )
+ Acb_ObjCollectTfo_rec( p, iFanout, fTerm );
+ Vec_IntPush( &p->vArray1, iObj );
+}
+Vec_Int_t * Acb_ObjCollectTfo( Acb_Ntk_t * p, int iObj, int fTerm )
+{
+ Vec_IntClear( &p->vArray1 );
+ Acb_NtkIncTravId( p );
+ Acb_ObjCollectTfo_rec( p, iObj, fTerm );
+ return &p->vArray1;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acb_ObjComputeLevelD( Acb_Ntk_t * p, int iObj )
+{
+ int * pFanins, iFanin, k, Level = 0;
+ Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
+ Level = Abc_MaxInt( Level, Acb_ObjLevelD(p, iFanin) );
+ return Acb_ObjSetLevelD( p, iObj, Level + !Acb_ObjIsCio(p, iObj) );
+}
+int Acb_NtkComputeLevelD( Acb_Ntk_t * p, Vec_Int_t * vTfo )
+{
+ int i, iObj, Level = 0;
+ if ( vTfo == NULL )
+ {
+ Acb_NtkCleanObjLevelD( p );
+ Acb_NtkForEachObj( p, iObj )
+ Acb_ObjComputeLevelD( p, iObj );
+ }
+ else
+ {
+ // it is assumed that vTfo contains CO nodes and level of new nodes was already updated
+ Vec_IntForEachEntry( vTfo, iObj, i )
+ Acb_ObjComputeLevelD( p, iObj );
+ }
+ Acb_NtkForEachCo( p, iObj, i )
+ Level = Abc_MaxInt( Level, Acb_ObjLevelD(p, iObj) );
+ p->LevelMax = Level;
+ return Level;
+}
+
+int Acb_ObjComputeLevelR( Acb_Ntk_t * p, int iObj )
+{
+ int iFanout, k, Level = 0;
+ Acb_ObjForEachFanout( p, iObj, iFanout, k )
+ Level = Abc_MaxInt( Level, Acb_ObjLevelR(p, iFanout) );
+ return Acb_ObjSetLevelR( p, iObj, Level + !Acb_ObjIsCio(p, iObj) );
+}
+int Acb_NtkComputeLevelR( Acb_Ntk_t * p, Vec_Int_t * vTfi )
+{
+ int i, iObj, Level = 0;
+ if ( vTfi == NULL )
+ {
+ Acb_NtkCleanObjLevelR( p );
+ Acb_NtkForEachObjReverse( p, iObj )
+ Acb_ObjComputeLevelR( p, iObj );
+ }
+ else
+ {
+ // it is assumed that vTfi contains CI nodes
+ Vec_IntForEachEntryReverse( vTfi, iObj, i )
+ Acb_ObjComputeLevelR( p, iObj );
+ }
+ Acb_NtkForEachCi( p, iObj, i )
+ Level = Abc_MaxInt( Level, Acb_ObjLevelR(p, iObj) );
+ assert( p->LevelMax == Level );
+ return Level;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acb_ObjSlack( Acb_Ntk_t * p, int iObj )
+{
+ assert( !Acb_ObjIsCio(p, iObj) + p->LevelMax >= Acb_ObjLevelD(p, iObj) + Acb_ObjLevelR(p, iObj) );
+ return !Acb_ObjIsCio(p, iObj) + p->LevelMax - Acb_ObjLevelD(p, iObj) - Acb_ObjLevelR(p, iObj);
+}
+int Acb_ObjComputePathD( Acb_Ntk_t * p, int iObj )
+{
+ int * pFanins, iFanin, k, Path = 0;
+ assert( !Acb_ObjIsCi(p, iObj) );
+ Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
+ if ( !Acb_ObjSlack(p, iFanin) )
+ Path += Acb_ObjPathD(p, iFanin);
+ return Acb_ObjSetPathD( p, iObj, Path );
+}
+int Acb_NtkComputePathsD( Acb_Ntk_t * p, Vec_Int_t * vTfo )
+{
+ int i, iObj, Path = 0;
+ if ( vTfo == NULL )
+ {
+ Acb_NtkCleanObjPathD( p );
+ Acb_NtkForEachCi( p, iObj, i )
+ if ( Acb_ObjLevelR(p, iObj) == p->LevelMax )
+ Acb_ObjSetPathD( p, iObj, 1 );
+ Acb_NtkForEachObj( p, iObj )
+ if ( !Acb_ObjIsCi(p, iObj) && !Acb_ObjSlack(p, iObj) )
+ Acb_ObjComputePathD( p, iObj );
+ }
+ else
+ {
+ // it is assumed that vTfo contains CO nodes
+ assert( Acb_ObjSlack(p, Vec_IntEntry(vTfo, 0)) );
+ Vec_IntForEachEntry( vTfo, iObj, i )
+ if ( !Acb_ObjSlack(p, iObj) )
+ Acb_ObjComputePathD( p, iObj );
+ else
+ Acb_ObjSetPathD( p, iObj, 0 );
+ }
+ Acb_NtkForEachCo( p, iObj, i )
+ Path += Acb_ObjPathD(p, iObj);
+ p->nPaths = Path;
+ return Path;
+}
+
+int Acb_ObjComputePathR( Acb_Ntk_t * p, int iObj )
+{
+ int iFanout, k, Path = 0;
+ assert( !Acb_ObjIsCo(p, iObj) );
+ Acb_ObjForEachFanout( p, iObj, iFanout, k )
+ if ( !Acb_ObjSlack(p, iFanout) )
+ Path += Acb_ObjPathR(p, iFanout);
+ return Acb_ObjSetPathR( p, iObj, Path );
+}
+int Acb_NtkComputePathsR( Acb_Ntk_t * p, Vec_Int_t * vTfi )
+{
+ int i, iObj, Level = p->LevelMax, Path = 0;
+ if ( vTfi == NULL )
+ {
+ Acb_NtkCleanObjPathR( p );
+ Acb_NtkForEachCo( p, iObj, i )
+ if ( Acb_ObjLevelD(p, iObj) == p->LevelMax )
+ Acb_ObjSetPathR( p, iObj, 1 );
+ Acb_NtkForEachObjReverse( p, iObj )
+ if ( !Acb_ObjIsCo(p, iObj) && !Acb_ObjSlack(p, iObj) )
+ Acb_ObjComputePathR( p, iObj );
+ }
+ else
+ {
+ // it is assumed that vTfi contains CI nodes
+ assert( Acb_ObjSlack(p, Vec_IntEntry(vTfi, 0)) );
+ Vec_IntForEachEntryReverse( vTfi, iObj, i )
+ if ( !Acb_ObjSlack(p, iObj) )
+ Acb_ObjComputePathR( p, iObj );
+ else
+ Acb_ObjSetPathR( p, iObj, 0 );
+ }
+ Acb_NtkForEachCi( p, iObj, i )
+ Path += Acb_ObjPathR(p, iObj);
+ assert( p->nPaths == Path );
+ return Path;
+}
+
+
+int Acb_NtkComputePaths( Acb_Ntk_t * p )
+{
+ int LevelD = Acb_NtkComputeLevelD( p, NULL );
+ int LevelR = Acb_NtkComputeLevelR( p, NULL );
+ int PathD = Acb_NtkComputePathsD( p, NULL );
+ int PathR = Acb_NtkComputePathsR( p, NULL );
+ assert( PathD == PathR );
+ return PathR;
+}
+
+void Abc_NtkComputePaths( Abc_Ntk_t * p )
+{
+ extern Acb_Ntk_t * Acb_NtkFromAbc( Abc_Ntk_t * p );
+ Acb_Ntk_t * pNtk = Acb_NtkFromAbc( p );
+
+ Acb_NtkCreateFanout( pNtk );
+ printf( "Computed %d paths.\n", Acb_NtkComputePaths(pNtk) );
+
+ Acb_ManFree( pNtk->pDesign );
+}
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Acb_ObjPath( Acb_Ntk_t * p, int iObj )
+{
+ return Acb_ObjPathD(p, iObj) + Acb_ObjPathR(p, iObj);
+}
+void Acb_ObjUpdateTiming( Acb_Ntk_t * p, int iObj )
+{
+}
+void Acb_NtkUpdateTiming( Acb_Ntk_t * p, int iObj )
+{
+ int i, Entry;
+ if ( iObj > 0 )
+ {
+ // assuming that level of the new nodes is up to date
+ Vec_Int_t * vTfi = Acb_ObjCollectTfi( p, iObj, 1 );
+ Vec_Int_t * vTfo = Acb_ObjCollectTfo( p, iObj, 1 );
+ int nLevelD = Acb_NtkComputeLevelD( p, vTfo );
+ int nLevelR = Acb_NtkComputeLevelR( p, vTfi );
+ int nPathD = Acb_NtkComputePathsD( p, vTfo );
+ int nPathR = Acb_NtkComputePathsR( p, vTfi );
+ Vec_IntForEachEntry( vTfi, Entry, i )
+ Acb_ObjUpdateTiming( p, Entry );
+ Vec_IntForEachEntry( vTfo, Entry, i )
+ Acb_ObjUpdateTiming( p, Entry );
+ }
+ else
+ {
+ int LevelD = Acb_NtkComputeLevelD( p, NULL );
+ int LevelR = Acb_NtkComputeLevelR( p, NULL );
+ int PathD = Acb_NtkComputePathsD( p, NULL );
+ int PathR = Acb_NtkComputePathsR( p, NULL );
+ Acb_NtkForEachNode( p, Entry )
+ Acb_ObjUpdateTiming( p, Entry );
+ }
+}
+
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+
+ABC_NAMESPACE_IMPL_END
+