mirror of https://github.com/YosysHQ/abc.git
355 lines
9.7 KiB
C
355 lines
9.7 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [resWin.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Resynthesis package.]
|
|
|
|
Synopsis [Windowing algorithm.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - January 15, 2007.]
|
|
|
|
Revision [$Id: resWin.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "abc.h"
|
|
#include "res.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Allocates the window.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Res_Win_t * Res_WinAlloc()
|
|
{
|
|
Res_Win_t * p;
|
|
p = ALLOC( Res_Win_t, 1 );
|
|
memset( p, 0, sizeof(Res_Win_t) );
|
|
p->vLevels = Vec_VecStart( 128 );
|
|
p->vLeaves = Vec_PtrAlloc( 512 );
|
|
p->vRoots = Vec_PtrAlloc( 512 );
|
|
p->vDivs = Vec_PtrAlloc( 512 );
|
|
return p;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Frees the window.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinFree( Res_Win_t * p )
|
|
{
|
|
Vec_VecFree( p->vLevels );
|
|
Vec_PtrFree( p->vLeaves );
|
|
Vec_PtrFree( p->vRoots );
|
|
Vec_PtrFree( p->vDivs );
|
|
free( p );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Collects nodes in the limited TFI of the node.]
|
|
|
|
Description [Marks the collected nodes.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinCollectNodeTfi( Res_Win_t * p )
|
|
{
|
|
Vec_Ptr_t * vFront;
|
|
Abc_Obj_t * pObj, * pFanin;
|
|
int i, k, m;
|
|
// expand storage for levels
|
|
if ( Vec_VecSize( p->vLevels ) <= (int)p->pNode->Level + p->nWinTfoMax )
|
|
Vec_VecExpand( p->vLevels, (int)p->pNode->Level + p->nWinTfoMax );
|
|
// start the frontier
|
|
Vec_VecClear( p->vLevels );
|
|
Res_WinAddNode( p, p->pNode );
|
|
// add one level at a time
|
|
Vec_VecForEachLevelReverseStartStop( p->vLevels, vFront, i, p->pNode->Level, p->nLevLeaves -1 )
|
|
{
|
|
Vec_PtrForEachEntry( vFront, pObj, k )
|
|
Abc_ObjForEachFanin( pObj, pFanin, m )
|
|
if ( !pFanin->fMarkA )
|
|
Res_WinAddNode( p, pFanin );
|
|
}
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Collect all the nodes that fanin into the window nodes.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinCollectLeaves( Res_Win_t * p )
|
|
{
|
|
Vec_Ptr_t * vLevel;
|
|
Abc_Obj_t * pObj;
|
|
int i, k;
|
|
// add the leaves
|
|
Vec_PtrClear( p->vLeaves );
|
|
// collect the nodes below the given level
|
|
Vec_VecForEachEntryStartStop( p->vLevels, pObj, i, k, 0, p->nLevLeaves )
|
|
Vec_PtrPush( p->vLeaves, pObj );
|
|
// remove leaves from the set
|
|
Vec_VecForEachLevelStartStop( p->vLevels, vLevel, i, 0, p->nLevLeaves )
|
|
Vec_PtrClear( vLevel );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Marks the TFO of the collected nodes up to the given level.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinSweepLeafTfo_rec( Abc_Obj_t * pObj, int nLevelLimit, Abc_Obj_t * pNode )
|
|
{
|
|
Abc_Obj_t * pFanout;
|
|
int i;
|
|
if ( Abc_ObjIsCo(pObj) || (int)pObj->Level > nLevelLimit || pObj == pNode )
|
|
return;
|
|
if ( Abc_NodeIsTravIdCurrent(pObj) )
|
|
return;
|
|
Abc_NodeSetTravIdCurrent( pObj );
|
|
Abc_ObjForEachFanout( pObj, pFanout, i )
|
|
Res_WinSweepLeafTfo_rec( pFanout, nLevelLimit, pNode );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Marks the TFO of the collected nodes up to the given level.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinSweepLeafTfo( Res_Win_t * p )
|
|
{
|
|
Abc_Obj_t * pObj;
|
|
int i;
|
|
Abc_NtkIncrementTravId( p->pNode->pNtk );
|
|
Vec_PtrForEachEntry( p->vLeaves, pObj, i )
|
|
Res_WinSweepLeafTfo_rec( pObj, p->pNode->Level + p->nWinTfoMax, p->pNode );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Recursively collects the roots.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinCollectRoots_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vRoots )
|
|
{
|
|
Abc_Obj_t * pFanout;
|
|
int i;
|
|
assert( Abc_ObjIsNode(pObj) );
|
|
assert( Abc_NodeIsTravIdCurrent(pObj) );
|
|
// check if the node has all fanouts marked
|
|
Abc_ObjForEachFanout( pObj, pFanout, i )
|
|
if ( !Abc_NodeIsTravIdCurrent(pObj) )
|
|
break;
|
|
// if some of the fanouts are unmarked, add the node to the root
|
|
if ( i < Abc_ObjFanoutNum(pObj) )
|
|
{
|
|
Vec_PtrPush( vRoots, pObj );
|
|
return;
|
|
}
|
|
// otherwise, call recursively
|
|
Abc_ObjForEachFanout( pObj, pFanout, i )
|
|
Res_WinCollectRoots_rec( pFanout, vRoots );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Collects the roots of the window.]
|
|
|
|
Description [Roots of the window are the nodes that have at least
|
|
one fanout that it not in the TFO of the leaves.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinCollectRoots( Res_Win_t * p )
|
|
{
|
|
Vec_PtrClear( p->vRoots );
|
|
Res_WinCollectRoots_rec( p->pNode, p->vRoots );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Recursively adds missing nodes and leaves.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinAddMissing_rec( Res_Win_t * p, Abc_Obj_t * pObj )
|
|
{
|
|
Abc_Obj_t * pFanin;
|
|
int i;
|
|
if ( pObj->fMarkA )
|
|
return;
|
|
if ( !Abc_NodeIsTravIdCurrent(pObj) )
|
|
{
|
|
Vec_PtrPush( p->vLeaves, pObj );
|
|
pObj->fMarkA = 1;
|
|
return;
|
|
}
|
|
Res_WinAddNode( p, pObj );
|
|
// visit the fanins of the node
|
|
Abc_ObjForEachFanin( pObj, pFanin, i )
|
|
Res_WinAddMissing_rec( p, pObj );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Adds to the window nodes and leaves in the TFI of the roots.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinAddMissing( Res_Win_t * p )
|
|
{
|
|
Abc_Obj_t * pObj;
|
|
int i;
|
|
Vec_PtrForEachEntry( p->vRoots, pObj, i )
|
|
Res_WinAddMissing_rec( p, pObj );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Unmarks the leaves and nodes of the window.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinUnmark( Res_Win_t * p )
|
|
{
|
|
Abc_Obj_t * pObj;
|
|
int i, k;
|
|
Vec_VecForEachEntry( p->vLevels, pObj, i, k )
|
|
pObj->fMarkA = 0;
|
|
Vec_PtrForEachEntry( p->vLeaves, pObj, i )
|
|
pObj->fMarkA = 0;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Labels the TFO of the node with the current trav ID.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Res_WinVisitNodeTfo( Res_Win_t * p )
|
|
{
|
|
// mark the TFO of the node
|
|
Res_WinSweepLeafTfo_rec( p->pNode, p->nLevDivMax, NULL );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes the window.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Res_WinCompute( Abc_Obj_t * pNode, int nWinTfiMax, int nWinTfoMax, Res_Win_t * p )
|
|
{
|
|
assert( Abc_ObjIsNode(pNode) );
|
|
assert( nWinTfiMax > 0 && nWinTfoMax > 0 );
|
|
// initialize the window
|
|
p->pNode = pNode;
|
|
p->nWinTfiMax = nWinTfiMax;
|
|
p->nWinTfoMax = nWinTfoMax;
|
|
p->nLevLeaves = ABC_MAX( 0, p->pNode->Level - p->nWinTfiMax - 1 );
|
|
p->nLevDivMax = 0;
|
|
Vec_PtrClear( p->vDivs );
|
|
// collect the nodes in TFI cone of pNode above the level of leaves (p->nLevLeaves)
|
|
Res_WinCollectNodeTfi( p );
|
|
// find the leaves of the window
|
|
Res_WinCollectLeaves( p );
|
|
// mark the TFO of the collected nodes up to the given level (p->pNode->Level + p->nWinTfoMax)
|
|
Res_WinSweepLeafTfo( p );
|
|
// find the roots of the window
|
|
Res_WinCollectRoots( p );
|
|
// add the nodes in the TFI of the roots that are not yet in the window
|
|
Res_WinAddMissing( p );
|
|
// unmark window nodes
|
|
Res_WinUnmark( p );
|
|
return 1;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|