mirror of https://github.com/YosysHQ/abc.git
376 lines
11 KiB
C
376 lines
11 KiB
C
/**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_ObjAddFanout( Acb_Ntk_t * p, int iObj )
|
|
{
|
|
int k, iFanin, * pFanins;
|
|
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
|
Vec_IntPush( Vec_WecEntry(&p->vFanouts, iFanin), iObj );
|
|
}
|
|
void Acb_ObjRemoveFanout( Acb_Ntk_t * p, int iObj )
|
|
{
|
|
int k, iFanin, * pFanins;
|
|
Acb_ObjForEachFaninFast( p, iObj, pFanins, iFanin, k )
|
|
Vec_IntRemove( Vec_WecEntry(&p->vFanouts, iFanin), iObj );
|
|
}
|
|
void Acb_NtkCreateFanout( Acb_Ntk_t * p )
|
|
{
|
|
int iObj;
|
|
Vec_WecInit( &p->vFanouts, Acb_NtkObjNumMax(p) );
|
|
Acb_NtkForEachObj( p, iObj )
|
|
Acb_ObjAddFanout( p, 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, 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 )
|
|
{
|
|
Acb_NtkComputeLevelD( p, NULL );
|
|
Acb_NtkComputeLevelR( p, NULL );
|
|
Acb_NtkComputePathsD( p, NULL );
|
|
Acb_NtkComputePathsR( p, NULL );
|
|
return p->nPaths;
|
|
}
|
|
|
|
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 );
|
|
Acb_NtkComputeLevelD( p, vTfo );
|
|
Acb_NtkComputeLevelR( p, vTfi );
|
|
Acb_NtkComputePathsD( p, vTfo );
|
|
Acb_NtkComputePathsR( p, vTfi );
|
|
Vec_IntForEachEntry( vTfi, Entry, i )
|
|
Acb_ObjUpdateTiming( p, Entry );
|
|
Vec_IntForEachEntry( vTfo, Entry, i )
|
|
Acb_ObjUpdateTiming( p, Entry );
|
|
}
|
|
else
|
|
{
|
|
Acb_NtkComputeLevelD( p, NULL );
|
|
Acb_NtkComputeLevelR( p, NULL );
|
|
Acb_NtkComputePathsD( p, NULL );
|
|
Acb_NtkComputePathsR( p, NULL );
|
|
Acb_NtkForEachNode( p, Entry )
|
|
Acb_ObjUpdateTiming( p, Entry );
|
|
}
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Acb_NtkUpdateNode( Acb_Ntk_t * p, int Pivot, word uTruth, Vec_Int_t * vSupp )
|
|
{
|
|
int i, iFanin;
|
|
Vec_WrdSetEntry( &p->vObjTruth, Pivot, uTruth );
|
|
Acb_ObjRemoveFanout( p, Pivot );
|
|
Acb_ObjRemoveFanins( p, Pivot );
|
|
Vec_IntForEachEntry( vSupp, iFanin, i )
|
|
Acb_ObjAddFanin( p, Pivot, iFanin );
|
|
Acb_ObjAddFanout( p, Pivot );
|
|
Acb_NtkUpdateTiming( p, Pivot );
|
|
Vec_IntErase( Vec_WecEntry(&p->vCnfs, Pivot) );
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|