Commit 7a6f335e by Alan Mishchenko

Improvements to buffering and sizing.

parent cb99a221
...@@ -387,8 +387,8 @@ static inline Abc_Obj_t * Abc_ObjChild0Data( Abc_Obj_t * pObj ) { return Ab ...@@ -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_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 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_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 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); *Vec_IntEntryP(p->pNtk->vPhases, Abc_ObjId(p)) ^= (1 << i); } 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 // 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; } static inline int Abc_AigNodeIsConst( Abc_Obj_t * pNode ) { assert(Abc_NtkIsStrash(Abc_ObjRegular(pNode)->pNtk)); return Abc_ObjRegular(pNode)->Type == ABC_OBJ_CONST1; }
......
...@@ -37,10 +37,11 @@ static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char **argv ); ...@@ -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_CommandTopo ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandBuffer ( 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_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_CommandMinsize ( Abc_Frame_t * pAbc, int argc, char **argv );
static int Scl_CommandMaxsize ( 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 ); static int Scl_CommandPrintBuf( Abc_Frame_t * pAbc, int argc, char **argv );
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -73,6 +74,7 @@ void Scl_Init( Abc_Frame_t * pAbc ) ...@@ -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", "maxsize", Scl_CommandMaxsize, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "upsize", Scl_CommandUpsize, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "upsize", Scl_CommandUpsize, 1 );
Cmd_CommandAdd( pAbc, "SCL mapping", "dnsize", Scl_CommandDnsize, 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 ); Cmd_CommandAdd( pAbc, "SCL mapping", "print_buf", Scl_CommandPrintBuf, 0 );
} }
void Scl_End( Abc_Frame_t * pAbc ) void Scl_End( Abc_Frame_t * pAbc )
...@@ -571,17 +573,18 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -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 * pNtk = Abc_FrameReadNtk(pAbc);
Abc_Ntk_t * pNtkRes; Abc_Ntk_t * pNtkRes;
int FanMin, FanMax, fAddInvs, fUseInvs, fBufPis; int FanMin, FanMax, FanMaxR, fAddInvs, fUseInvs, fBufPis;
int c, fVerbose; int c, fVerbose;
int fOldAlgo = 0; int fOldAlgo = 0;
FanMin = 6; FanMin = 6;
FanMax = 14; FanMax = 14;
FanMaxR = 0;
fAddInvs = 0; fAddInvs = 0;
fUseInvs = 0; fUseInvs = 0;
fBufPis = 0; fBufPis = 0;
fVerbose = 0; fVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "NMaixpvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "NMRaixpvh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -607,6 +610,17 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -607,6 +610,17 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( FanMax < 0 ) if ( FanMax < 0 )
goto usage; goto usage;
break; 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': case 'a':
fOldAlgo ^= 1; fOldAlgo ^= 1;
break; break;
...@@ -649,7 +663,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -649,7 +663,7 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( fAddInvs ) if ( fAddInvs )
pNtkRes = Abc_SclBufferPhase( pNtk, fVerbose ); pNtkRes = Abc_SclBufferPhase( pNtk, fVerbose );
else if ( fOldAlgo ) else if ( fOldAlgo )
pNtkRes = Abc_SclPerformBuffering( pNtk, FanMax, fUseInvs, fVerbose ); pNtkRes = Abc_SclPerformBuffering( pNtk, FanMaxR, FanMax, fUseInvs, fVerbose );
else else
pNtkRes = Abc_SclBufPerform( pNtk, FanMin, FanMax, fBufPis, fVerbose ); pNtkRes = Abc_SclBufPerform( pNtk, FanMin, FanMax, fBufPis, fVerbose );
if ( pNtkRes == NULL ) if ( pNtkRes == NULL )
...@@ -662,10 +676,11 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -662,10 +676,11 @@ int Scl_CommandBuffer( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: 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 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-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-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-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-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" ); fprintf( pAbc->Err, "\t-x : toggle using interters instead of buffers [default = %s]\n", fUseInvs? "yes": "no" );
...@@ -1248,6 +1263,94 @@ usage: ...@@ -1248,6 +1263,94 @@ usage:
SeeAlso [] 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 ) int Scl_CommandPrintBuf( Abc_Frame_t * pAbc, int argc, char **argv )
{ {
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
......
...@@ -78,6 +78,28 @@ static inline int Abc_BufEdgeSlack( Buf_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t ...@@ -78,6 +78,28 @@ static inline int Abc_BufEdgeSlack( Buf_Man_t * p, Abc_Obj_t * pObj, Abc_Obj_t
/**Function************************************************************* /**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.] Synopsis [Removes buffers and inverters.]
Description [] Description []
...@@ -244,6 +266,7 @@ Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose ) ...@@ -244,6 +266,7 @@ Abc_Ntk_t * Abc_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose )
pNtkNew = Abc_NtkDupDfs( pNtk ); pNtkNew = Abc_NtkDupDfs( pNtk );
if ( fVerbose ) if ( fVerbose )
printf( "Max depth = %d.\n", Abc_SclCountMaxPhases(pNtkNew) ); printf( "Max depth = %d.\n", Abc_SclCountMaxPhases(pNtkNew) );
Abc_SclReportDupFanins( pNtkNew );
return pNtkNew; return pNtkNew;
} }
...@@ -292,6 +315,20 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ) ...@@ -292,6 +315,20 @@ int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose )
SeeAlso [] 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 Abc_NodeCompareLevels( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
{ {
int Diff = Abc_ObjLevel(*pp1) - Abc_ObjLevel(*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 ...@@ -364,12 +401,16 @@ Abc_Obj_t * Abc_SclPerformBufferingOne( Abc_Obj_t * pObj, int Degree, int fUseIn
Vec_PtrFree( vFanouts ); Vec_PtrFree( vFanouts );
Abc_ObjAddFanin( pBuffer, pObj ); Abc_ObjAddFanin( pBuffer, pObj );
pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer ); pBuffer->Level = Abc_SclComputeReverseLevel( pBuffer );
if ( fUseInvs )
Abc_NodeInvUpdateFanPolarity( pBuffer );
return 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; Abc_Obj_t * pFanout;
int i; int i, nOldFanNum;
if ( Abc_NodeIsTravIdCurrent( pObj ) ) if ( Abc_NodeIsTravIdCurrent( pObj ) )
return; return;
Abc_NodeSetTravIdCurrent( pObj ); Abc_NodeSetTravIdCurrent( pObj );
...@@ -379,14 +420,32 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, in ...@@ -379,14 +420,32 @@ void Abc_SclPerformBuffering_rec( Abc_Obj_t * pObj, int Degree, int fUseInvs, in
assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) ); assert( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) );
// buffer fanouts and collect reverse levels // buffer fanouts and collect reverse levels
Abc_ObjForEachFanout( pObj, pFanout, i ) 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 // perform buffering as long as needed
nOldFanNum = Abc_ObjFanoutNum(pObj);
while ( Abc_ObjFanoutNum(pObj) > Degree ) while ( Abc_ObjFanoutNum(pObj) > Degree )
Abc_SclPerformBufferingOne( pObj, Degree, fUseInvs, fVerbose ); 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 // compute the new level of the node
pObj->Level = Abc_SclComputeReverseLevel( pObj ); 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; Vec_Int_t * vCiLevs;
Abc_Ntk_t * pNew; Abc_Ntk_t * pNew;
...@@ -394,7 +453,11 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, in ...@@ -394,7 +453,11 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, in
int i; int i;
assert( Abc_NtkHasMapping(p) ); assert( Abc_NtkHasMapping(p) );
if ( fUseInvs ) if ( fUseInvs )
{
printf( "Warning!!! Using inverters instead of buffers.\n" ); 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 // remember CI levels
vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) ); vCiLevs = Vec_IntAlloc( Abc_NtkCiNum(p) );
Abc_NtkForEachCi( p, pObj, i ) Abc_NtkForEachCi( p, pObj, i )
...@@ -402,13 +465,16 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, in ...@@ -402,13 +465,16 @@ Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fUseInvs, in
// perform buffering // perform buffering
Abc_NtkIncrementTravId( p ); Abc_NtkIncrementTravId( p );
Abc_NtkForEachCi( p, pObj, i ) Abc_NtkForEachCi( p, pObj, i )
Abc_SclPerformBuffering_rec( pObj, Degree, fUseInvs, fVerbose ); Abc_SclPerformBuffering_rec( pObj, DegreeR, Degree, fUseInvs, fVerbose );
// recompute logic levels // recompute logic levels
Abc_NtkForEachCi( p, pObj, i ) Abc_NtkForEachCi( p, pObj, i )
pObj->Level = Vec_IntEntry( vCiLevs, i ); pObj->Level = Vec_IntEntry( vCiLevs, i );
Abc_NtkForEachNode( p, pObj, i ) Abc_NtkForEachNode( p, pObj, i )
Abc_ObjLevelNew( pObj ); Abc_ObjLevelNew( pObj );
Vec_IntFree( vCiLevs ); Vec_IntFree( vCiLevs );
// if phases are present
if ( p->vPhases )
Vec_IntFillExtra( p->vPhases, Abc_NtkObjNumMax(p), 0 );
// duplication in topo order // duplication in topo order
pNew = Abc_NtkDupDfs( p ); pNew = Abc_NtkDupDfs( p );
Abc_SclCheckNtk( pNew, fVerbose ); Abc_SclCheckNtk( pNew, fVerbose );
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "sclSize.h" #include "sclSize.h"
#include "map/mio/mio.h" #include "map/mio/mio.h"
#include "misc/vec/vecWec.h"
ABC_NAMESPACE_IMPL_START ABC_NAMESPACE_IMPL_START
...@@ -121,7 +122,7 @@ static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise ...@@ -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( "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( "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( "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" ); printf( "\n" );
} }
void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fPrintPath ) 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 * ...@@ -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 ); SC_Pair * pDepOut = Abc_SclObjDept( p, pObj );
Scl_LibPinDeparture( pTime, pDepIn, pSlewIn, pLoad, pDepOut ); 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 ) void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
{ {
SC_Timings * pRTime; SC_Timings * pRTime;
...@@ -213,8 +219,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept ) ...@@ -213,8 +219,7 @@ void Abc_SclTimeNode( SC_Man * p, Abc_Obj_t * pObj, int fDept )
float LoadFall = pLoad->fall; float LoadFall = pLoad->fall;
float DeptRise = 0; float DeptRise = 0;
float DeptFall = 0; float DeptFall = 0;
// float Value = Abc_MaxFloat(pLoad->fall, pLoad->rise) / (p->EstLoadAve * p->EstLoadMax); float Value = p->EstLoadMax ? Abc_SclObjLoadValue( p, pObj ) : 0;
float Value = 0.5 * (pLoad->fall + pLoad->rise) / (p->EstLoadAve * p->EstLoadMax);
if ( Abc_ObjIsCo(pObj) ) if ( Abc_ObjIsCo(pObj) )
{ {
if ( !fDept ) if ( !fDept )
...@@ -325,8 +330,6 @@ void Abc_SclTimeNtkRecompute( SC_Man * p, float * pArea, float * pDelay, int fRe ...@@ -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) ); p->pSlack[i] = Abc_MaxFloat( 0.0, Abc_SclObjGetSlack(p, pObj, D) );
} }
} }
if ( p->nEstNodes )
printf( "Estimated nodes = %d.\n", p->nEstNodes );
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -626,7 +629,7 @@ void Abc_SclPrintBuffersOne( SC_Man * p, Abc_Obj_t * pObj, int nOffset ) ...@@ -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( "%6.0f ps) ", Abc_SclObjTimePs(p, pObj, 0) );
printf( "l =%5.0f ff ", Abc_SclObjLoadFf(p, pObj, 0 ) ); printf( "l =%5.0f ff ", Abc_SclObjLoadFf(p, pObj, 0 ) );
printf( "s =%5.0f ps ", Abc_SclObjSlewPs(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 ) if ( nOffset == 0 )
{ {
printf( "L =%5.0f ff ", SC_LibCapFf( p->pLib, Abc_SclCountNonBufferLoad(p, pObj) ) ); 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 ) ...@@ -698,6 +701,103 @@ int Abc_SclInputDriveOk( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell )
return 1; 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 /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -122,6 +122,7 @@ static inline int Abc_SclObjLegal( SC_Man * p, Abc_Obj_t * pObj, float D ) ...@@ -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_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_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_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 /// /// FUNCTION DEFINITIONS ///
...@@ -397,7 +398,7 @@ extern Abc_Ntk_t * Abc_SclUnBufferPerform( Abc_Ntk_t * pNtk, int fVerbose ); ...@@ -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_SclUnBufferPhase( Abc_Ntk_t * pNtk, int fVerbose );
extern Abc_Ntk_t * Abc_SclBufferPhase( 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 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 ); extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax, int fBufPis, int fVerbose );
/*=== sclDnsize.c ===============================================================*/ /*=== sclDnsize.c ===============================================================*/
extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ); extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );
......
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