Commit 9b02fe59 by Alan Mishchenko

Added buffering based on combinational merging.

parent 329831bd
......@@ -2355,6 +2355,10 @@ SOURCE=.\src\map\scl\scl.h
# End Source File
# Begin Source File
SOURCE=.\src\map\scl\sclBuff.c
# End Source File
# Begin Source File
SOURCE=.\src\map\scl\sclFile.c
# End Source File
# Begin Source File
......
......@@ -705,6 +705,7 @@ extern ABC_DLL void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t *
extern ABC_DLL Abc_Ntk_t * Abc_NtkStartRead( char * pName );
extern ABC_DLL void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk );
extern ABC_DLL Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk );
extern ABC_DLL Abc_Ntk_t * Abc_NtkDupDfs( Abc_Ntk_t * pNtk );
extern ABC_DLL Abc_Ntk_t * Abc_NtkDupTransformMiter( Abc_Ntk_t * pNtk );
extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNodeName, int fUseAllCis );
extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateConeArray( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, int fUseAllCis );
......
......@@ -350,9 +350,6 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
return NULL;
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
// transfer level
Abc_NtkForEachCi( pNtk, pObj, i )
pObj->pCopy->Level = pObj->Level;
// copy the internal nodes
if ( Abc_NtkIsStrash(pNtk) )
{
......@@ -406,6 +403,42 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
pNtk->pCopy = pNtkNew;
return pNtkNew;
}
Abc_Ntk_t * Abc_NtkDupDfs( Abc_Ntk_t * pNtk )
{
Vec_Ptr_t * vNodes;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObj, * pFanin;
int i, k;
if ( pNtk == NULL )
return NULL;
assert( !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsNetlist(pNtk) );
// start the network
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
// copy the internal nodes
vNodes = Abc_NtkDfs( pNtk, 0 );
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj, 0 );
Vec_PtrFree( vNodes );
// reconnect all objects (no need to transfer attributes on edges)
Abc_NtkForEachObj( pNtk, pObj, i )
if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
Abc_ObjForEachFanin( pObj, pFanin, k )
if ( pObj->pCopy && pFanin->pCopy )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
// duplicate the EXDC Ntk
if ( pNtk->pExdc )
pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
if ( pNtk->pExcare )
pNtkNew->pExcare = Abc_NtkDup( (Abc_Ntk_t *)pNtk->pExcare );
// duplicate timing manager
if ( pNtk->pManTime )
Abc_NtkTimeInitialize( pNtkNew, pNtk );
// check correctness
if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
pNtk->pCopy = pNtkNew;
return pNtkNew;
}
/**Function*************************************************************
......
......@@ -9385,14 +9385,17 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
extern Aig_Man_t * Abc_NtkToDarBmc( Abc_Ntk_t * pNtk, Vec_Int_t ** pvMap );
extern void Abc2_NtkTestGia( char * pFileName, int fVerbose );
extern void Saig_ManBmcTerSimTestPo( Aig_Man_t * p );
extern int Abc_SclCheckNtk( Abc_Ntk_t * p );
extern void Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree );
if ( pNtk )
{
/*
Aig_Man_t * pAig = Abc_NtkToDar( pNtk, 0, 1 );
Saig_ManBmcTerSimTestPo( pAig );
Aig_ManStop( pAig );
*/
Abc_SclPerformBuffering( pNtk, nDecMax );
/*
extern Abc_Ntk_t * Abc_NtkShareXor( Abc_Ntk_t * pNtk );
Abc_Ntk_t * pNtkRes = Abc_NtkShareXor( pNtk );
......
SRC += src/map/scl/scl.c \
src/map/scl/sclBuff.c \
src/map/scl/sclFile.c \
src/map/scl/sclSize.c \
src/map/scl/sclTime.c \
......
......@@ -27,11 +27,12 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static int Scl_CommandRead ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandWrite( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandPrint( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandRead ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandWrite ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandPrint ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandGsize ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char **argv );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
......@@ -50,11 +51,12 @@ static int Scl_CommandGsize( Abc_Frame_t * pAbc, int argc, char **argv );
***********************************************************************/
void Scl_Init( Abc_Frame_t * pAbc )
{
Cmd_CommandAdd( pAbc, "SC mapping", "read_scl", Scl_CommandRead, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "write_scl", Scl_CommandWrite, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "print_scl", Scl_CommandPrint, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "stime", Scl_CommandStime, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "gsize", Scl_CommandGsize, 1 );
Cmd_CommandAdd( pAbc, "SC mapping", "read_scl", Scl_CommandRead, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "write_scl", Scl_CommandWrite, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "print_scl", Scl_CommandPrint, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "stime", Scl_CommandStime, 0 );
Cmd_CommandAdd( pAbc, "SC mapping", "gsize", Scl_CommandGsize, 1 );
Cmd_CommandAdd( pAbc, "SC mapping", "buffer", Scl_CommandBuffer, 1 );
}
void Scl_End( Abc_Frame_t * pAbc )
{
......@@ -321,6 +323,83 @@ usage:
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
{
extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose );
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
Abc_Ntk_t * pNtkRes;
int Degree;
int c, fVerbose;
Degree = 3;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Nvh" ) ) != EOF )
{
switch ( c )
{
case 'N':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-N\" should be followed by a positive integer.\n" );
goto usage;
}
Degree = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( Degree < 0 )
goto usage;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
Abc_Print( -1, "Empty network.\n" );
return 1;
}
if ( !Abc_NtkIsLogic(pNtk) )
{
Abc_Print( -1, "This command can only be applied to a logic network.\n" );
return 1;
}
// modify the current network
pNtkRes = Abc_SclPerformBuffering( pNtk, Degree, fVerbose );
if ( pNtkRes == NULL )
{
Abc_Print( -1, "The command has failed.\n" );
return 1;
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
return 0;
usage:
Abc_Print( -2, "usage: buffer [-N num] [-vh]\n" );
Abc_Print( -2, "\t performs buffering of the mapped network\n" );
Abc_Print( -2, "\t-N <num> : the number of refinement iterations [default = %d]\n", Degree );
Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" );
Abc_Print( -2, "\t-h : print the command usage\n");
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
......
/**CFile****************************************************************
FileName [sclBuff.c]
SystemName [ABC: Logic synthesis and verification system.]
Synopsis [Standard-cell library representation.]
Author [Alan Mishchenko, Niklas Een]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - August 24, 2012.]
Revision [$Id: sclBuff.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
***********************************************************************/
#include "base/abc/abc.h"
#include "map/mio/mio.h"
#include "sclInt.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Make sure the network has no dangling nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose )
{
Abc_Obj_t * pObj, * pFanin;
int i, k, fFlag = 0;
Abc_NtkIncrementTravId( p );
Abc_NtkForEachCi( p, pObj, i )
Abc_NodeSetTravIdCurrent( pObj );
Abc_NtkForEachNode( p, pObj, i )
{
Abc_ObjForEachFanin( pObj, pFanin, k )
if ( !Abc_NodeIsTravIdCurrent( pFanin ) )
printf( "obj %d and its fanin %d are not in the topo order\n", Abc_ObjId(pObj), Abc_ObjId(pFanin) ), fFlag = 1;
Abc_NodeSetTravIdCurrent( pObj );
if ( Abc_ObjFanoutNum(pObj) == 0 )
printf( "node %d has no fanout\n", Abc_ObjId(pObj) ), fFlag = 1;
}
if ( !fFlag && fVerbose )
printf( "The network is in topo order and no dangling nodes.\n" );
return 1;
}
/**Function*************************************************************
Synopsis [Make sure the network has no dangling nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_SclCheckNtk2( Abc_Ntk_t * p )
{
Abc_Obj_t * pObj, * pFanout;
int i, k, fFlag = 0;
Abc_NtkStartReverseLevels( p, 0 );
Abc_NtkForEachNode( p, pObj, i )
{
if ( Abc_ObjFanoutNum(pObj) <= 3 )
continue;
printf( "Node %5d (%2d) : fans = %3d ", i, Abc_ObjLevel(pObj), Abc_ObjFanoutNum(pObj) );
Abc_ObjForEachFanout( pObj, pFanout, k )
printf( "%d ", Abc_ObjReverseLevel(pFanout) );
printf( "\n" );
}
return 1;
}
/**Function*************************************************************
Synopsis [Performs buffering of the mapped network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
{
int Diff = Abc_ObjLevel(*pp1) - Abc_ObjLevel(*pp2);
if ( Diff < 0 )
return -1;
if ( Diff > 0 )
return 1;
Diff = (*pp1)->Id - (*pp2)->Id;
if ( Diff < 0 )
return -1;
if ( Diff > 0 )
return 1;
return 0;
}
int Abc_SclComputeReverseLevel( Abc_Obj_t * pObj )
{
Abc_Obj_t * pFanout;
int i, Level = 0;
Abc_ObjForEachFanout( pObj, pFanout, i )
Level = Abc_MaxInt( Level, pFanout->Level );
return Level + 1;
}
Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fVerbose )
{
Vec_Ptr_t * vFanouts;
Abc_Obj_t * pBuffer, * pFanout;
int i, Degree0 = Degree;
assert( Abc_ObjFanoutNum(pObj) > Degree );
// collect fanouts and sort by reverse level
vFanouts = Vec_PtrAlloc( Abc_ObjFanoutNum(pObj) );
Abc_NodeCollectFanouts( pObj, vFanouts );
Vec_PtrSort( vFanouts, Abc_NodeCompareLevels );
// select the first Degree fanouts
pBuffer = Abc_NtkCreateNodeBuf( pObj->pNtk, NULL );
// check if it is possible to not increase level
if ( Vec_PtrSize(vFanouts) < 2 * Degree )
{
Abc_Obj_t * pFanPrev = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, Vec_PtrSize(vFanouts)-1-Degree);
Abc_Obj_t * pFanThis = (Abc_Obj_t *)Vec_PtrEntry(vFanouts, Degree-1);
Abc_Obj_t * pFanLast = (Abc_Obj_t *)Vec_PtrEntryLast(vFanouts);
if ( Abc_ObjLevel(pFanThis) == Abc_ObjLevel(pFanLast) &&
Abc_ObjLevel(pFanPrev) < Abc_ObjLevel(pFanThis) )
{
// find the first one whose level is the same as last
Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i )
if ( Abc_ObjLevel(pFanout) == Abc_ObjLevel(pFanLast) )
break;
assert( i < Vec_PtrSize(vFanouts) );
if ( i > 1 )
Degree = i;
}
// make the last two more well-balanced
if ( Degree == Degree0 && Degree > Vec_PtrSize(vFanouts) - Degree )
Degree = Vec_PtrSize(vFanouts)/2 + (Vec_PtrSize(vFanouts) & 1);
assert( Degree <= Degree0 );
}
// select fanouts
Vec_PtrForEachEntryStop( Abc_Obj_t *, vFanouts, pFanout, i, Degree )
Abc_ObjPatchFanin( pFanout, pObj, pBuffer );
if ( fVerbose )
{
printf( "%5d : ", Abc_ObjId(pObj) );
Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i )
printf( "%d%s ", Abc_ObjLevel(pFanout), i == Degree-1 ? " " : "" );
printf( "\n" );
}
Vec_PtrFree( vFanouts );
Abc_ObjAddFanin( pBuffer, pObj );
pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
return pBuffer;
}
void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fVerbose )
{
Abc_Obj_t * pFanout;
int i;
if ( Abc_NodeIsTravIdCurrent( pObj ) )
return;
Abc_NodeSetTravIdCurrent( pObj );
pObj->Level = 0;
if ( Abc_ObjIsCo(pObj) )
return;
assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) );
// buffer fanouts and collect reverse levels
Abc_ObjForEachFanout( pObj, pFanout, i )
Abc_SclPerformBuffering_rec( pFanout, Degree, fVerbose );
// perform buffering as long as needed
while ( Abc_ObjFanoutNum(pObj) > Degree )
Abc_SclPerformBufferingOne( pObj, Degree, fVerbose );
// compute the new level of the node
pObj->Level = Abc_SclComputeReverseLevel( pObj );
}
Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose )
{
Abc_Ntk_t * pNew;
Abc_Obj_t * pObj;
int i;
assert( Abc_NtkHasMapping(p) );
Abc_NtkIncrementTravId( p );
Abc_NtkForEachCi( p, pObj, i )
Abc_SclPerformBuffering_rec( pObj, Degree, fVerbose );
Abc_NtkLevel( p );
// duplication in topo order
pNew = Abc_NtkDupDfs( p );
Abc_SclCheckNtk( pNew, fVerbose );
// Abc_NtkDelete( pNew );
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END
......@@ -385,7 +385,6 @@ extern int Abc_SclCellFind( SC_Lib * p, char * pName );
extern void Abc_SclLinkCells( SC_Lib * p );
extern void Abc_SclPrintCells( SC_Lib * p );
ABC_NAMESPACE_HEADER_END
#endif
......
/**CFile****************************************************************
FileName [sclIo.c]
FileName [sclSize.c]
SystemName [ABC: Logic synthesis and verification system.]
......@@ -12,7 +12,7 @@
Date [Ver. 1.0. Started - August 24, 2012.]
Revision [$Id: sclIo.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
Revision [$Id: sclSize.c,v 1.0 2012/08/24 00:00:00 alanmi Exp $]
***********************************************************************/
......
......@@ -259,6 +259,23 @@ Abc_Obj_t * Abc_SclFindMostCritical( SC_Man * p, int * pfRise, Vec_Ptr_t * vNode
assert( pPivot != NULL );
return pPivot;
}
Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t * pNode )
{
Abc_Obj_t * pObj, * pPivot = NULL;
float fMaxArr = 0;
int i;
Abc_ObjForEachFanin( pNode, pObj, i )
{
SC_Pair * pArr = Abc_SclObjArr( p, pObj );
if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise, *pfRise = 1, pPivot = pObj;
if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall, *pfRise = 0, pPivot = pObj;
}
assert( pPivot != NULL );
return pPivot;
}
void Abc_SclCriticalPathPrint( SC_Man * p, Vec_Ptr_t * vNodes )
{
}
void Abc_SclTimeNtkPrint( SC_Man * p, Vec_Ptr_t * vNodes )
{
/*
......@@ -385,6 +402,7 @@ void Abc_SclTimeNtk( SC_Man * p )
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
Synopsis []
......@@ -399,6 +417,7 @@ void Abc_SclTimeNtk( SC_Man * p )
void Abc_SclTimePerform( SC_Lib * pLib, void * pNtk )
{
SC_Man * p;
p = Abc_SclManAlloc( pLib, (Abc_Ntk_t *)pNtk );
Abc_SclTimeNtk( p );
Abc_SclManFree( p );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment