summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/base/abc/abc.h4
-rw-r--r--src/map/scl/scl.c115
-rw-r--r--src/map/scl/sclBuffer.c76
-rw-r--r--src/map/scl/sclSize.c112
-rw-r--r--src/map/scl/sclSize.h3
5 files changed, 290 insertions, 20 deletions
diff --git a/src/base/abc/abc.h b/src/base/abc/abc.h
index bd0c5bba..a9178f38 100644
--- a/src/base/abc/abc.h
+++ b/src/base/abc/abc.h
@@ -387,8 +387,8 @@ static inline Abc_Obj_t * Abc_ObjChild0Data( Abc_Obj_t * pObj ) { return Ab
static inline Abc_Obj_t * Abc_ObjChild1Data( Abc_Obj_t * pObj ) { return Abc_ObjNotCond( (Abc_Obj_t *)Abc_ObjFanin1(pObj)->pData, Abc_ObjFaninC1(pObj) ); }
static inline Abc_Obj_t * Abc_ObjFromLit( Abc_Ntk_t * p, int iLit ) { return Abc_ObjNotCond( Abc_NtkObj(p, Abc_Lit2Var(iLit)), Abc_LitIsCompl(iLit) ); }
static inline int Abc_ObjToLit( Abc_Obj_t * p ) { return Abc_Var2Lit( Abc_ObjId(Abc_ObjRegular(p)), Abc_ObjIsComplement(p) ); }
-static inline int Abc_ObjFaninPhase( Abc_Obj_t * p, int i ) { assert(p->pNtk->vPhases); return (Vec_IntEntry(p->pNtk->vPhases, Abc_ObjId(p)) >> i) & 1; }
-static inline void Abc_ObjFaninFlipPhase( Abc_Obj_t * p,int i){ assert(p->pNtk->vPhases); *Vec_IntEntryP(p->pNtk->vPhases, Abc_ObjId(p)) ^= (1 << i); }
+static inline int Abc_ObjFaninPhase( Abc_Obj_t * p, int i ) { assert(p->pNtk->vPhases); assert( i >= 0 && i < Abc_ObjFaninNum(p) ); return (Vec_IntEntry(p->pNtk->vPhases, Abc_ObjId(p)) >> i) & 1; }
+static inline void Abc_ObjFaninFlipPhase( Abc_Obj_t * p,int i){ assert(p->pNtk->vPhases); assert( i >= 0 && i < Abc_ObjFaninNum(p) ); *Vec_IntEntryP(p->pNtk->vPhases, Abc_ObjId(p)) ^= (1 << i); }
// checking the AIG node types
static inline int Abc_AigNodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_NtkIsStrash(Abc_ObjRegular(pNode)->pNtk)); return Abc_ObjRegular(pNode)->Type == ABC_OBJ_CONST1; }
diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c
index e9c4d22c..e2b3d1ce 100644
--- a/src/map/scl/scl.c
+++ b/src/map/scl/scl.c
@@ -37,10 +37,11 @@ static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandTopo ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandBuffer ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandUnBuffer( Abc_Frame_t * pAbc, int argc, char **argv );
-static int Scl_CommandUpsize ( Abc_Frame_t * pAbc, int argc, char **argv );
-static int Scl_CommandDnsize ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandMinsize ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandMaxsize ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int Scl_CommandUpsize ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int Scl_CommandDnsize ( Abc_Frame_t * pAbc, int argc, char **argv );
+static int Scl_CommandBsize ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandPrintBuf( Abc_Frame_t * pAbc, int argc, char **argv );
////////////////////////////////////////////////////////////////////////
@@ -73,6 +74,7 @@ void Scl_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "SCL mapping", "maxsize", Scl_CommandMaxsize, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "upsize", Scl_CommandUpsize, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "dnsize", Scl_CommandDnsize, 1 );
+ Cmd_CommandAdd( pAbc, "SCL mapping", "bsize", Scl_CommandBsize, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "print_buf", Scl_CommandPrintBuf, 0 );
}
void Scl_End( Abc_Frame_t * pAbc )
@@ -571,17 +573,18 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
Abc_Ntk_t * pNtkRes;
- int FanMin, FanMax, fAddInvs, fUseInvs, fBufPis;
+ int FanMin, FanMax, FanMaxR, fAddInvs, fUseInvs, fBufPis;
int c, fVerbose;
int fOldAlgo = 0;
FanMin = 6;
FanMax = 14;
+ FanMaxR = 0;
fAddInvs = 0;
fUseInvs = 0;
fBufPis = 0;
fVerbose = 0;
Extra_UtilGetoptReset();
- while ( ( c = Extra_UtilGetopt( argc, argv, "NMaixpvh" ) ) != EOF )
+ while ( ( c = Extra_UtilGetopt( argc, argv, "NMRaixpvh" ) ) != EOF )
{
switch ( c )
{
@@ -607,6 +610,17 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( FanMax < 0 )
goto usage;
break;
+ case 'R':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-R\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ FanMaxR = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( FanMaxR < 0 )
+ goto usage;
+ break;
case 'a':
fOldAlgo ^= 1;
break;
@@ -649,7 +663,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( fAddInvs )
pNtkRes = Abc_SclBufferPhase( pNtk, fVerbose );
else if ( fOldAlgo )
- pNtkRes = Abc_SclPerformBuffering( pNtk, FanMax, fUseInvs, fVerbose );
+ pNtkRes = Abc_SclPerformBuffering( pNtk, FanMaxR, FanMax, fUseInvs, fVerbose );
else
pNtkRes = Abc_SclBufPerform( pNtk, FanMin, FanMax, fBufPis, fVerbose );
if ( pNtkRes == NULL )
@@ -662,10 +676,11 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0;
usage:
- fprintf( pAbc->Err, "usage: buffer [-NM num] [-aixpvh]\n" );
+ fprintf( pAbc->Err, "usage: buffer [-NMR num] [-aixpvh]\n" );
fprintf( pAbc->Err, "\t performs buffering of the mapped network\n" );
fprintf( pAbc->Err, "\t-N <num> : the min fanout considered by the algorithm [default = %d]\n", FanMin );
fprintf( pAbc->Err, "\t-M <num> : the max allowed fanout count of node/buffer [default = %d]\n", FanMax );
+ fprintf( pAbc->Err, "\t-R <num> : the max allowed fanout count of root node [default = %d]\n", FanMaxR );
fprintf( pAbc->Err, "\t-a : toggle using old algorithm [default = %s]\n", fOldAlgo? "yes": "no" );
fprintf( pAbc->Err, "\t-i : toggle adding interters instead of buffering [default = %s]\n", fAddInvs? "yes": "no" );
fprintf( pAbc->Err, "\t-x : toggle using interters instead of buffers [default = %s]\n", fUseInvs? "yes": "no" );
@@ -1248,6 +1263,94 @@ usage:
SeeAlso []
***********************************************************************/
+int Scl_CommandBsize( Abc_Frame_t * pAbc, int argc, char **argv )
+{
+ extern Abc_Ntk_t * Abc_SclBuffSizeStep( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads );
+ Abc_Ntk_t * pNtkRes;
+ int c;
+ int fUseWireLoads = 1;
+ int nTreeCRatio = 0;
+
+ Extra_UtilGetoptReset();
+ while ( ( c = Extra_UtilGetopt( argc, argv, "Xch" ) ) != EOF )
+ {
+ switch ( c )
+ {
+ case 'X':
+ if ( globalUtilOptind >= argc )
+ {
+ Abc_Print( -1, "Command line switch \"-X\" should be followed by a positive integer.\n" );
+ goto usage;
+ }
+ nTreeCRatio = atoi(argv[globalUtilOptind]);
+ globalUtilOptind++;
+ if ( nTreeCRatio < 0 )
+ goto usage;
+ break;
+ case 'c':
+ fUseWireLoads ^= 1;
+ break;
+ case 'h':
+ goto usage;
+ default:
+ goto usage;
+ }
+ }
+
+ if ( Abc_FrameReadNtk(pAbc) == NULL )
+ {
+ fprintf( pAbc->Err, "There is no current network.\n" );
+ return 1;
+ }
+ if ( !Abc_NtkHasMapping(Abc_FrameReadNtk(pAbc)) )
+ {
+ fprintf( pAbc->Err, "The current network is not mapped.\n" );
+ return 1;
+ }
+ if ( !Abc_SclCheckNtk(Abc_FrameReadNtk(pAbc), 0) )
+ {
+ fprintf( pAbc->Err, "The current network is not in a topo order (run \"topo\").\n" );
+ return 1;
+ }
+ if ( pAbc->pLibScl == NULL )
+ {
+ fprintf( pAbc->Err, "There is no Liberty library available.\n" );
+ return 1;
+ }
+ if ( Abc_FrameReadNtk(pAbc)->vPhases == 0 )
+ {
+ fprintf( pAbc->Err, "There is no phases available.\n" );
+ return 1;
+ }
+ pNtkRes = Abc_SclBuffSizeStep( (SC_Lib *)pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nTreeCRatio, fUseWireLoads );
+ if ( pNtkRes == NULL )
+ {
+ Abc_Print( -1, "The command has failed.\n" );
+ return 1;
+ }
+ Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
+ return 0;
+
+usage:
+ fprintf( pAbc->Err, "usage: bsize [-X num] [-ch]\n" );
+ fprintf( pAbc->Err, "\t performs STA using Liberty library\n" );
+ fprintf( pAbc->Err, "\t-X : min Cout/Cave ratio for tree estimations [default = %d]\n", nTreeCRatio );
+ fprintf( pAbc->Err, "\t-c : toggle using wire-loads if specified [default = %s]\n", fUseWireLoads? "yes": "no" );
+ fprintf( pAbc->Err, "\t-h : print the help massage\n" );
+ return 1;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
int Scl_CommandPrintBuf( Abc_Frame_t * pAbc, int argc, char **argv )
{
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
diff --git a/src/map/scl/sclBuffer.c b/src/map/scl/sclBuffer.c
index 9dc43499..83a305bd 100644
--- a/src/map/scl/sclBuffer.c
+++ b/src/map/scl/sclBuffer.c
@@ -78,6 +78,28 @@ static inline int Abc_BufEdgeSlack( Buf_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t
/**Function*************************************************************
+ Synopsis [Make sure fanins of gates are not duplicated.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_SclReportDupFanins( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj, * pFanin, * pFanin2;
+ int i, k, k2;
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ Abc_ObjForEachFanin( pObj, pFanin, k )
+ Abc_ObjForEachFanin( pObj, pFanin2, k2 )
+ if ( k != k2 && pFanin == pFanin2 )
+ printf( "Node %d has dup fanin %d.\n", i, Abc_ObjId(pFanin) );
+}
+
+/**Function*************************************************************
+
Synopsis [Removes buffers and inverters.]
Description []
@@ -244,6 +266,7 @@ Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose )
pNtkNew = Abc_NtkDupDfs( pNtk );
if ( fVerbose )
printf( "Max depth = %d.\n", Abc_SclCountMaxPhases(pNtkNew) );
+ Abc_SclReportDupFanins( pNtkNew );
return pNtkNew;
}
@@ -292,6 +315,20 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose )
SeeAlso []
***********************************************************************/
+void Abc_NodeInvUpdateFanPolarity( Abc_Obj_t * pObj )
+{
+ Abc_Obj_t * pFanout;
+ int i;
+ assert( Abc_SclObjIsBufInv(pObj) );
+ Abc_ObjForEachFanout( pObj, pFanout, i )
+ {
+ if ( Abc_SclObjIsBufInv(pFanout) )
+ Abc_NodeInvUpdateFanPolarity( pFanout );
+ else
+ Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) );
+ }
+}
+
int Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
{
int Diff = Abc_ObjLevel(*pp1) - Abc_ObjLevel(*pp2);
@@ -364,12 +401,16 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseIn
Vec_PtrFree( vFanouts );
Abc_ObjAddFanin( pBuffer, pObj );
pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
+ if ( fUseInvs )
+ Abc_NodeInvUpdateFanPolarity( pBuffer );
return pBuffer;
}
-void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, int fVerbose )
+void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int DegreeR, int Degree, int fUseInvs, int fVerbose )
{
+ Vec_Ptr_t * vFanouts;
+ Abc_Obj_t * pBuffer;
Abc_Obj_t * pFanout;
- int i;
+ int i, nOldFanNum;
if ( Abc_NodeIsTravIdCurrent( pObj ) )
return;
Abc_NodeSetTravIdCurrent( pObj );
@@ -379,14 +420,32 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, in
assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) );
// buffer fanouts and collect reverse levels
Abc_ObjForEachFanout( pObj, pFanout, i )
- Abc_SclPerformBuffering_rec( pFanout, Degree, fUseInvs, fVerbose );
+ Abc_SclPerformBuffering_rec( pFanout, DegreeR, Degree, fUseInvs, fVerbose );
// perform buffering as long as needed
+ nOldFanNum = Abc_ObjFanoutNum(pObj);
while ( Abc_ObjFanoutNum(pObj) > Degree )
Abc_SclPerformBufferingOne( pObj, Degree, fUseInvs, fVerbose );
+ // add yet another level of buffers
+ if ( DegreeR && nOldFanNum > DegreeR )
+ {
+ if ( fUseInvs )
+ pBuffer = Abc_NtkCreateNodeInv( pObj->pNtk, NULL );
+ else
+ pBuffer = Abc_NtkCreateNodeBuf( pObj->pNtk, NULL );
+ vFanouts = Vec_PtrAlloc( Abc_ObjFanoutNum(pObj) );
+ Abc_NodeCollectFanouts( pObj, vFanouts );
+ Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, i )
+ Abc_ObjPatchFanin( pFanout, pObj, pBuffer );
+ Vec_PtrFree( vFanouts );
+ Abc_ObjAddFanin( pBuffer, pObj );
+ pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
+ if ( fUseInvs )
+ Abc_NodeInvUpdateFanPolarity( pBuffer );
+ }
// compute the new level of the node
pObj->Level = Abc_SclComputeReverseLevel( pObj );
}
-Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, int fVerbose )
+Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int DegreeR, int Degree, int fUseInvs, int fVerbose )
{
Vec_Int_t * vCiLevs;
Abc_Ntk_t * pNew;
@@ -394,7 +453,11 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, in
int i;
assert( Abc_NtkHasMapping(p) );
if ( fUseInvs )
+ {
printf( "Warning!!! Using inverters instead of buffers.\n" );
+ if ( p->vPhases == NULL )
+ printf( "The phases are not given. The result will not verify.\n" );
+ }
// remember CI levels
vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) );
Abc_NtkForEachCi( p, pObj, i )
@@ -402,13 +465,16 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, in
// perform buffering
Abc_NtkIncrementTravId( p );
Abc_NtkForEachCi( p, pObj, i )
- Abc_SclPerformBuffering_rec( pObj, Degree, fUseInvs, fVerbose );
+ Abc_SclPerformBuffering_rec( pObj, DegreeR, Degree, fUseInvs, fVerbose );
// recompute logic levels
Abc_NtkForEachCi( p, pObj, i )
pObj->Level = Vec_IntEntry( vCiLevs, i );
Abc_NtkForEachNode( p, pObj, i )
Abc_ObjLevelNew( pObj );
Vec_IntFree( vCiLevs );
+ // if phases are present
+ if ( p->vPhases )
+ Vec_IntFillExtra( p->vPhases, Abc_NtkObjNumMax(p), 0 );
// duplication in topo order
pNew = Abc_NtkDupDfs( p );
Abc_SclCheckNtk( pNew, fVerbose );
diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c
index 2efa22ee..86c81589 100644
--- a/src/map/scl/sclSize.c
+++ b/src/map/scl/sclSize.c
@@ -20,6 +20,7 @@
#include "sclSize.h"
#include "map/mio/mio.h"
+#include "misc/vec/vecWec.h"
ABC_NAMESPACE_IMPL_START
@@ -121,7 +122,7 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise
printf( "Cout =%5.0f ff ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) );
printf( "Cmax =%5.0f ff ", pCell ? SC_CellPin(pCell, pCell->n_inputs)->max_out_cap : 0.0 );
printf( "G =%5.1f ", pCell ? Abc_SclObjLoadAve(p, pObj) / SC_CellPinCap(pCell, 0) : 0.0 );
- printf( "SL =%5.1f ps", Abc_SclObjSlack(p, pObj) );
+ printf( "SL =%5.1f ps", Abc_SclObjSlackPs(p, pObj) );
printf( "\n" );
}
void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath )
@@ -201,6 +202,11 @@ static inline void Abc_SclDeptFanin( SC_Man * p, SC_Timing * pTime, Abc_Obj_t *
SC_Pair * pDepOut = Abc_SclObjDept( p, pObj );
Scl_LibPinDeparture( pTime, pDepIn, pSlewIn, pLoad, pDepOut );
}
+static inline float Abc_SclObjLoadValue( SC_Man * p, Abc_Obj_t * pObj )
+{
+// float Value = Abc_MaxFloat(pLoad->fall, pLoad->rise) / (p->EstLoadAve * p->EstLoadMax);
+ return 0.5 * (Abc_SclObjLoad(p, pObj)->fall + Abc_SclObjLoad(p, pObj)->rise) / (p->EstLoadAve * p->EstLoadMax);
+}
void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
{
SC_Timings * pRTime;
@@ -213,8 +219,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
float LoadFall = pLoad->fall;
float DeptRise = 0;
float DeptFall = 0;
-// float Value = Abc_MaxFloat(pLoad->fall, pLoad->rise) / (p->EstLoadAve * p->EstLoadMax);
- float Value = 0.5 * (pLoad->fall + pLoad->rise) / (p->EstLoadAve * p->EstLoadMax);
+ float Value = p->EstLoadMax ? Abc_SclObjLoadValue( p, pObj ) : 0;
if ( Abc_ObjIsCo(pObj) )
{
if ( !fDept )
@@ -325,8 +330,6 @@ void Abc_SclTimeNtkRecompute( SC_Man * p, float * pArea, float * pDelay, int fRe
p->pSlack[i] = Abc_MaxFloat( 0.0, Abc_SclObjGetSlack(p, pObj, D) );
}
}
- if ( p->nEstNodes )
- printf( "Estimated nodes = %d.\n", p->nEstNodes );
}
/**Function*************************************************************
@@ -626,7 +629,7 @@ void Abc_SclPrintBuffersOne( SC_Man * p, Abc_Obj_t * pObj, int nOffset )
printf( "%6.0f ps) ", Abc_SclObjTimePs(p, pObj, 0) );
printf( "l =%5.0f ff ", Abc_SclObjLoadFf(p, pObj, 0 ) );
printf( "s =%5.0f ps ", Abc_SclObjSlewPs(p, pObj, 0 ) );
- printf( "sl =%5.0f ps ", Abc_SclObjSlack(p, pObj) );
+ printf( "sl =%5.0f ps ", Abc_SclObjSlackPs(p, pObj) );
if ( nOffset == 0 )
{
printf( "L =%5.0f ff ", SC_LibCapFf( p->pLib, Abc_SclCountNonBufferLoad(p, pObj) ) );
@@ -698,6 +701,103 @@ int Abc_SclInputDriveOk( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell )
return 1;
}
+/**Function*************************************************************
+
+ Synopsis [Select nodes that need to be buffered.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Vec_Wec_t * Abc_SclSelectSplitNodes( SC_Man * p, Abc_Ntk_t * pNtk )
+{
+ Vec_Wec_t * vSplits;
+ Vec_Int_t * vCrits, * vNonCrits, * vLevel;
+ Abc_Obj_t * pObj, * pFanout;
+ int i, k;
+ assert( p->EstLoadMax > 0 );
+ vCrits = Vec_IntAlloc( 1000 );
+ vNonCrits = Vec_IntAlloc( 1000 );
+ vSplits = Vec_WecAlloc( 1000 );
+ Abc_NtkForEachNodeCi( pNtk, pObj, i )
+ {
+ if ( Abc_SclObjLoadValue(p, pObj) < 1 )
+ {
+// printf( "%d ", Abc_ObjFanoutNum(pObj) );
+ continue;
+ }
+/*
+ printf( "%d : %.0f ", i, 0.5 * (Abc_SclObjLoad(p, pObj)->fall + Abc_SclObjLoad(p, pObj)->rise) );
+ Abc_ObjForEachFanout( pObj, pFanout, k )
+ printf( "%.1f ", Abc_SclGatePinCapAve(p->pLib, Abc_SclObjCell(p, pFanout)) );
+ printf( "\n" );
+*/
+ // skip non-critical nodes
+// if ( Abc_SclObjSlack(p, pObj) > 100 )
+// continue;
+ // collect non-critical fanouts of the node
+ Vec_IntClear( vCrits );
+ Vec_IntClear( vNonCrits );
+ Abc_ObjForEachFanout( pObj, pFanout, k )
+ if ( Abc_SclObjSlack(p, pFanout) < 100 )
+ Vec_IntPush( vCrits, Abc_ObjId(pFanout) );
+ else
+ Vec_IntPush( vNonCrits, Abc_ObjId(pFanout) );
+// assert( Vec_IntSize(vNonCrits) < Abc_ObjFanoutNum(pObj) );
+ // skip if there is nothing to split
+// if ( Vec_IntSize(vNonCrits) < 2 )
+// continue;
+ // remember them
+ vLevel = Vec_WecPushLevel( vSplits );
+ Vec_IntPush( vLevel, i );
+ Vec_IntAppend( vLevel, vCrits );
+ // remember them
+ vLevel = Vec_WecPushLevel( vSplits );
+ Vec_IntPush( vLevel, i );
+ Vec_IntAppend( vLevel, vNonCrits );
+ }
+ Vec_IntFree( vCrits );
+ Vec_IntFree( vNonCrits );
+ // print out
+ printf( "Collected %d nodes to split.\n", Vec_WecSize(vSplits) );
+ return vSplits;
+}
+void Abc_SclPerformSplit( SC_Man * p, Abc_Ntk_t * pNtk, Vec_Wec_t * vSplits )
+{
+ Abc_Obj_t * pObj, * pObjInv, * pFanout;
+ Vec_Int_t * vLevel;
+ int i, k;
+ assert( pNtk->vPhases != NULL );
+ Vec_WecForEachLevel( vSplits, vLevel, i )
+ {
+ pObj = Abc_NtkObj( pNtk, Vec_IntEntry(vLevel, 0) );
+ pObjInv = Abc_NtkCreateNodeInv( pNtk, pObj );
+ Abc_NtkForEachObjVecStart( vLevel, pNtk, pFanout, k, 1 )
+ {
+ Abc_ObjFaninFlipPhase( pFanout, Abc_NodeFindFanin(pFanout, pObj) );
+ Abc_ObjPatchFanin( pFanout, pObj, pObjInv );
+ }
+ }
+ Vec_IntFillExtra( pNtk->vPhases, Abc_NtkObjNumMax(pNtk), 0 );
+}
+Abc_Ntk_t * Abc_SclBuffSizeStep( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads )
+{
+ SC_Man * p;
+ Vec_Wec_t * vSplits;
+ p = Abc_SclManStart( pLib, pNtk, fUseWireLoads, 1, 0, nTreeCRatio );
+ Abc_SclTimeNtkPrint( p, 0, 0 );
+ if ( p->nEstNodes )
+ printf( "Estimated nodes = %d.\n", p->nEstNodes );
+ vSplits = Abc_SclSelectSplitNodes( p, pNtk );
+ Abc_SclPerformSplit( p, pNtk, vSplits );
+ Vec_WecFree( vSplits );
+ Abc_SclManFree( p );
+ return Abc_NtkDupDfs( pNtk );
+}
+
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h
index c467ba1c..9656b55a 100644
--- a/src/map/scl/sclSize.h
+++ b/src/map/scl/sclSize.h
@@ -122,6 +122,7 @@ static inline int Abc_SclObjLegal( SC_Man * p, Abc_Obj_t * pObj, float D )
static inline double Abc_SclObjLoadFf( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibCapFf( p->pLib, fRise ? Abc_SclObjLoad(p, pObj)->rise : Abc_SclObjLoad(p, pObj)->fall); }
static inline double Abc_SclObjTimePs( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibTimePs(p->pLib, fRise ? Abc_SclObjTime(p, pObj)->rise : Abc_SclObjTime(p, pObj)->fall); }
static inline double Abc_SclObjSlewPs( SC_Man * p, Abc_Obj_t * pObj, int fRise ) { return SC_LibTimePs(p->pLib, fRise ? Abc_SclObjSlew(p, pObj)->rise : Abc_SclObjSlew(p, pObj)->fall); }
+static inline double Abc_SclObjSlackPs( SC_Man * p, Abc_Obj_t * pObj ) { return SC_LibTimePs(p->pLib, Abc_SclObjSlack(p, pObj)); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
@@ -397,7 +398,7 @@ extern Abc_Ntk_t * Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose );
extern Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose );
extern Abc_Ntk_t * Abc_SclBufferPhase( Abc_Ntk_t * pNtk, int fVerbose );
extern int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose );
-extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, int fVerbose );
+extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int DegreeR, int Degree, int fUseInvs, int fVerbose );
extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fBufPis, int fVerbose );
/*=== sclDnsize.c ===============================================================*/
extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );