diff options
Diffstat (limited to 'src/map/scl')
-rw-r--r-- | src/map/scl/module.make | 1 | ||||
-rw-r--r-- | src/map/scl/scl.c | 99 | ||||
-rw-r--r-- | src/map/scl/sclBuff.c | 219 | ||||
-rw-r--r-- | src/map/scl/sclInt.h | 1 | ||||
-rw-r--r-- | src/map/scl/sclSize.c | 4 | ||||
-rw-r--r-- | src/map/scl/sclTime.c | 19 |
6 files changed, 330 insertions, 13 deletions
diff --git a/src/map/scl/module.make b/src/map/scl/module.make index d6731980..1e926e4b 100644 --- a/src/map/scl/module.make +++ b/src/map/scl/module.make @@ -1,4 +1,5 @@ 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 \ diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index 73cd6552..cbe7b3aa 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.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 /// diff --git a/src/map/scl/sclBuff.c b/src/map/scl/sclBuff.c new file mode 100644 index 00000000..d435ae92 --- /dev/null +++ b/src/map/scl/sclBuff.c @@ -0,0 +1,219 @@ +/**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 + diff --git a/src/map/scl/sclInt.h b/src/map/scl/sclInt.h index 8b9b0eec..b9a78f75 100644 --- a/src/map/scl/sclInt.h +++ b/src/map/scl/sclInt.h @@ -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 diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index 8270bcea..850a2501 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -1,6 +1,6 @@ /**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 $] ***********************************************************************/ diff --git a/src/map/scl/sclTime.c b/src/map/scl/sclTime.c index 45eb4ee5..160478c2 100644 --- a/src/map/scl/sclTime.c +++ b/src/map/scl/sclTime.c @@ -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 ); |