Commit a9afe7e8 by Alan Mishchenko

Improvements to post-mapping re-sizing.

parent 710835f8
...@@ -718,24 +718,26 @@ void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk ) ...@@ -718,24 +718,26 @@ void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk )
pTimeDef = Abc_NtkReadDefaultInputDrive( pNtk ); pTimeDef = Abc_NtkReadDefaultInputDrive( pNtk );
if ( pTimeDef->Rise != 0.0 || pTimeDef->Fall != 0.0 ) if ( pTimeDef->Rise != 0.0 || pTimeDef->Fall != 0.0 )
fprintf( pFile, ".default_input_drive %g %g\n", pTimeDef->Rise, pTimeDef->Fall ); fprintf( pFile, ".default_input_drive %g %g\n", pTimeDef->Rise, pTimeDef->Fall );
Abc_NtkForEachPi( pNtk, pNode, i ) if ( Abc_NodeReadInputDrive( pNtk, 0 ) )
{ Abc_NtkForEachPi( pNtk, pNode, i )
pTime = Abc_NodeReadInputDrive( pNtk, i ); {
if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall ) pTime = Abc_NodeReadInputDrive( pNtk, i );
continue; if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall )
fprintf( pFile, ".input_drive %s %g %g\n", Abc_ObjName(Abc_ObjFanout0(pNode)), pTime->Rise, pTime->Fall ); continue;
} fprintf( pFile, ".input_drive %s %g %g\n", Abc_ObjName(Abc_ObjFanout0(pNode)), pTime->Rise, pTime->Fall );
}
pTimeDef = Abc_NtkReadDefaultOutputLoad( pNtk ); pTimeDef = Abc_NtkReadDefaultOutputLoad( pNtk );
if ( pTimeDef->Rise != 0.0 || pTimeDef->Fall != 0.0 ) if ( pTimeDef->Rise != 0.0 || pTimeDef->Fall != 0.0 )
fprintf( pFile, ".default_output_load %g %g\n", pTimeDef->Rise, pTimeDef->Fall ); fprintf( pFile, ".default_output_load %g %g\n", pTimeDef->Rise, pTimeDef->Fall );
Abc_NtkForEachPo( pNtk, pNode, i ) if ( Abc_NodeReadOutputLoad( pNtk, 0 ) )
{ Abc_NtkForEachPo( pNtk, pNode, i )
pTime = Abc_NodeReadOutputLoad( pNtk, i ); {
if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall ) pTime = Abc_NodeReadOutputLoad( pNtk, i );
continue; if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall )
fprintf( pFile, ".output_load %s %g %g\n", Abc_ObjName(Abc_ObjFanin0(pNode)), pTime->Rise, pTime->Fall ); continue;
} fprintf( pFile, ".output_load %s %g %g\n", Abc_ObjName(Abc_ObjFanin0(pNode)), pTime->Rise, pTime->Fall );
}
fprintf( pFile, "\n" ); fprintf( pFile, "\n" );
} }
......
...@@ -580,15 +580,17 @@ usage: ...@@ -580,15 +580,17 @@ usage:
***********************************************************************/ ***********************************************************************/
int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv ) int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv )
{ {
SC_UpSizePars Pars, * pPars = &Pars; SC_SizePars Pars, * pPars = &Pars;
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
int c; int c;
memset( pPars, 0, sizeof(SC_UpSizePars) ); memset( pPars, 0, sizeof(SC_SizePars) );
pPars->nIters = 1000; pPars->nIters = 1000;
pPars->nIterNoChange = 50; pPars->nIterNoChange = 50;
pPars->Window = 2; pPars->Window = 2;
pPars->Ratio = 10; pPars->Ratio = 10;
pPars->Notches = 20; pPars->Notches = 1000;
pPars->DelayUser = 0;
pPars->DelayGap = 0;
pPars->TimeOut = 0; pPars->TimeOut = 0;
pPars->fUseDept = 1; pPars->fUseDept = 1;
pPars->fUseWireLoads = 1; pPars->fUseWireLoads = 1;
...@@ -596,7 +598,7 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -596,7 +598,7 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv )
pPars->fVerbose = 0; pPars->fVerbose = 0;
pPars->fVeryVerbose = 0; pPars->fVeryVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "IJWRNTcsdvwh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "IJWRNDGTcsdvwh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -655,6 +657,26 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -655,6 +657,26 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv )
if ( pPars->Notches < 0 ) if ( pPars->Notches < 0 )
goto usage; goto usage;
break; break;
case 'D':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-D\" should be followed by a positive integer.\n" );
goto usage;
}
pPars->DelayUser = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->DelayUser < 0 )
goto usage;
break;
case 'G':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-G\" should be followed by a positive integer.\n" );
goto usage;
}
pPars->DelayGap = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'T': case 'T':
if ( globalUtilOptind >= argc ) if ( globalUtilOptind >= argc )
{ {
...@@ -713,13 +735,15 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -713,13 +735,15 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv )
return 0; return 0;
usage: usage:
fprintf( pAbc->Err, "usage: upsize [-IJWRNT num] [-csdvwh]\n" ); fprintf( pAbc->Err, "usage: upsize [-IJWRNDGT num] [-csdvwh]\n" );
fprintf( pAbc->Err, "\t selectively increases gate sizes on the critical path\n" ); fprintf( pAbc->Err, "\t selectively increases gate sizes on the critical path\n" );
fprintf( pAbc->Err, "\t-I <num> : the number of upsizing iterations to perform [default = %d]\n", pPars->nIters ); fprintf( pAbc->Err, "\t-I <num> : the number of upsizing iterations to perform [default = %d]\n", pPars->nIters );
fprintf( pAbc->Err, "\t-J <num> : the number of iterations without improvement to stop [default = %d]\n", pPars->nIterNoChange ); fprintf( pAbc->Err, "\t-J <num> : the number of iterations without improvement to stop [default = %d]\n", pPars->nIterNoChange );
fprintf( pAbc->Err, "\t-W <num> : delay window (in percent) of near-critical COs [default = %d]\n", pPars->Window ); fprintf( pAbc->Err, "\t-W <num> : delay window (in percent) of near-critical COs [default = %d]\n", pPars->Window );
fprintf( pAbc->Err, "\t-R <num> : ratio of critical nodes (in percent) to update [default = %d]\n", pPars->Ratio ); fprintf( pAbc->Err, "\t-R <num> : ratio of critical nodes (in percent) to update [default = %d]\n", pPars->Ratio );
fprintf( pAbc->Err, "\t-N <num> : limit on discrete upsizing steps at a node [default = %d]\n", pPars->Notches ); fprintf( pAbc->Err, "\t-N <num> : limit on discrete upsizing steps at a node [default = %d]\n", pPars->Notches );
fprintf( pAbc->Err, "\t-D <num> : delay target set by the user, in picoseconds [default = %d]\n", pPars->DelayUser );
fprintf( pAbc->Err, "\t-G <num> : delay gap during updating, in picoseconds [default = %d]\n", pPars->DelayGap );
fprintf( pAbc->Err, "\t-T <num> : approximate timeout in seconds [default = %d]\n", pPars->TimeOut ); fprintf( pAbc->Err, "\t-T <num> : approximate timeout in seconds [default = %d]\n", pPars->TimeOut );
fprintf( pAbc->Err, "\t-c : toggle using wire-loads if specified [default = %s]\n", pPars->fUseWireLoads? "yes": "no" ); fprintf( pAbc->Err, "\t-c : toggle using wire-loads if specified [default = %s]\n", pPars->fUseWireLoads? "yes": "no" );
fprintf( pAbc->Err, "\t-s : toggle using slack based on departure times [default = %s]\n", pPars->fUseDept? "yes": "no" ); fprintf( pAbc->Err, "\t-s : toggle using slack based on departure times [default = %s]\n", pPars->fUseDept? "yes": "no" );
...@@ -743,13 +767,15 @@ usage: ...@@ -743,13 +767,15 @@ usage:
***********************************************************************/ ***********************************************************************/
int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv ) int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv )
{ {
SC_DnSizePars Pars, * pPars = &Pars; SC_SizePars Pars, * pPars = &Pars;
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
int c; int c;
memset( pPars, 0, sizeof(SC_DnSizePars) ); memset( pPars, 0, sizeof(SC_SizePars) );
pPars->DUser = 0;
pPars->nIters = 5; pPars->nIters = 5;
pPars->nIterNoChange = 50; pPars->nIterNoChange = 50;
pPars->Notches = 1000;
pPars->DelayUser = 0;
pPars->DelayGap = 1000;
pPars->TimeOut = 0; pPars->TimeOut = 0;
pPars->fUseDept = 1; pPars->fUseDept = 1;
pPars->fUseWireLoads = 1; pPars->fUseWireLoads = 1;
...@@ -757,21 +783,10 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -757,21 +783,10 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv )
pPars->fVerbose = 0; pPars->fVerbose = 0;
pPars->fVeryVerbose = 0; pPars->fVeryVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "DIJTcsdvwh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "IJNDGTcsdvwh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
case 'D':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-D\" should be followed by a positive integer.\n" );
goto usage;
}
pPars->DUser = atof(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->DUser < 0 )
goto usage;
break;
case 'I': case 'I':
if ( globalUtilOptind >= argc ) if ( globalUtilOptind >= argc )
{ {
...@@ -794,6 +809,37 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -794,6 +809,37 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv )
if ( pPars->nIterNoChange < 0 ) if ( pPars->nIterNoChange < 0 )
goto usage; goto usage;
break; break;
case 'N':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-N\" should be followed by a positive integer.\n" );
goto usage;
}
pPars->Notches = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->Notches < 0 )
goto usage;
break;
case 'D':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-D\" should be followed by a positive integer.\n" );
goto usage;
}
pPars->DelayUser = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->DelayUser < 0 )
goto usage;
break;
case 'G':
if ( globalUtilOptind >= argc )
{
Abc_Print( -1, "Command line switch \"-G\" should be followed by a positive integer.\n" );
goto usage;
}
pPars->DelayGap = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
break;
case 'T': case 'T':
if ( globalUtilOptind >= argc ) if ( globalUtilOptind >= argc )
{ {
...@@ -852,11 +898,13 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv ) ...@@ -852,11 +898,13 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv )
return 0; return 0;
usage: usage:
fprintf( pAbc->Err, "usage: dnsize [-DIJT num] [-csdvwh]\n" ); fprintf( pAbc->Err, "usage: dnsize [-IJNDGT num] [-csdvwh]\n" );
fprintf( pAbc->Err, "\t selectively decreases gate sizes while maintaining delay\n" ); fprintf( pAbc->Err, "\t selectively decreases gate sizes while maintaining delay\n" );
fprintf( pAbc->Err, "\t-D <num> : the target max delay after downsizing in picosecs [default = %.2f]\n", pPars->DUser );
fprintf( pAbc->Err, "\t-I <num> : the number of upsizing iterations to perform [default = %d]\n", pPars->nIters ); fprintf( pAbc->Err, "\t-I <num> : the number of upsizing iterations to perform [default = %d]\n", pPars->nIters );
fprintf( pAbc->Err, "\t-J <num> : the number of iterations without improvement to stop [default = %d]\n", pPars->nIterNoChange ); fprintf( pAbc->Err, "\t-J <num> : the number of iterations without improvement to stop [default = %d]\n", pPars->nIterNoChange );
fprintf( pAbc->Err, "\t-N <num> : limit on discrete upsizing steps at a node [default = %d]\n", pPars->Notches );
fprintf( pAbc->Err, "\t-D <num> : delay target set by the user, in picoseconds [default = %d]\n", pPars->DelayUser );
fprintf( pAbc->Err, "\t-G <num> : delay gap during updating, in picoseconds [default = %d]\n", pPars->DelayGap );
fprintf( pAbc->Err, "\t-T <num> : approximate timeout in seconds [default = %d]\n", pPars->TimeOut ); fprintf( pAbc->Err, "\t-T <num> : approximate timeout in seconds [default = %d]\n", pPars->TimeOut );
fprintf( pAbc->Err, "\t-c : toggle using wire-loads if specified [default = %s]\n", pPars->fUseWireLoads? "yes": "no" ); fprintf( pAbc->Err, "\t-c : toggle using wire-loads if specified [default = %s]\n", pPars->fUseWireLoads? "yes": "no" );
fprintf( pAbc->Err, "\t-s : toggle using slack based on departure times [default = %s]\n", pPars->fUseDept? "yes": "no" ); fprintf( pAbc->Err, "\t-s : toggle using slack based on departure times [default = %s]\n", pPars->fUseDept? "yes": "no" );
......
...@@ -99,7 +99,7 @@ void Abc_SclFindWindow( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int_t ** p ...@@ -99,7 +99,7 @@ void Abc_SclFindWindow( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int_t ** p
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_SclCheckImprovement( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vNodes, Vec_Int_t * vEvals ) int Abc_SclCheckImprovement( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vNodes, Vec_Int_t * vEvals, int Notches, int DelayGap )
{ {
Abc_Obj_t * pTemp; Abc_Obj_t * pTemp;
SC_Cell * pCellOld, * pCellNew; SC_Cell * pCellOld, * pCellNew;
...@@ -114,11 +114,13 @@ clk = Abc_Clock(); ...@@ -114,11 +114,13 @@ clk = Abc_Clock();
Abc_SclLoadStore( p, pObj ); Abc_SclLoadStore( p, pObj );
// try different gate sizes for this node // try different gate sizes for this node
gateBest = -1; gateBest = -1;
dGainBest = -ABC_INFINITY; //0.0; dGainBest = -SC_LibTimeFromPs(p->pLib, (float)DelayGap);
SC_RingForEachCell( pCellOld, pCellNew, i ) SC_RingForEachCellRev( pCellOld, pCellNew, i )
{ {
if ( pCellNew->area >= pCellOld->area ) if ( pCellNew->area >= pCellOld->area )
continue; continue;
if ( i > Notches )
break;
// set new cell // set new cell
Abc_SclObjSetCell( p, pObj, pCellNew ); Abc_SclObjSetCell( p, pObj, pCellNew );
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew ); Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
...@@ -240,7 +242,7 @@ void Abc_SclDnsizePrint( SC_Man * p, int Iter, int nAttempts, int nOverlaps, int ...@@ -240,7 +242,7 @@ void Abc_SclDnsizePrint( SC_Man * p, int Iter, int nAttempts, int nOverlaps, int
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_DnSizePars * pPars ) void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars )
{ {
SC_Man * p; SC_Man * p;
Abc_Obj_t * pObj; Abc_Obj_t * pObj;
...@@ -250,17 +252,18 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_DnSizePars * pPar ...@@ -250,17 +252,18 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_DnSizePars * pPar
if ( pPars->fVerbose ) if ( pPars->fVerbose )
{ {
printf( "Downsizing parameters: " ); printf( "Parameters: " );
printf( "Delay =%8.2f ps. ", pPars->DUser ); printf( "Iters =%5d. ", pPars->nIters );
printf( "Iters =%5d. ", pPars->nIters ); printf( "UseDept =%2d. ", pPars->fUseDept );
printf( "UseDept =%2d. ", pPars->fUseDept ); printf( "UseWL =%2d. ", pPars->fUseWireLoads );
printf( "UseWL =%2d. ", pPars->fUseWireLoads ); printf( "Target =%5d ps. ", pPars->DelayUser );
printf( "Timeout =%4d sec", pPars->TimeOut ); printf( "DelayGap =%3d ps. ", pPars->DelayGap );
printf( "Timeout =%4d sec", pPars->TimeOut );
printf( "\n" ); printf( "\n" );
} }
// prepare the manager; collect init stats // prepare the manager; collect init stats
p = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, SC_LibTimeFromPs(pLib, pPars->DUser) ); p = Abc_SclManStart( pLib, pNtk, pPars->fUseWireLoads, pPars->fUseDept, SC_LibTimeFromPs(pLib, pPars->DelayUser) );
p->timeTotal = Abc_Clock(); p->timeTotal = Abc_Clock();
assert( p->vGatesBest == NULL ); assert( p->vGatesBest == NULL );
p->vGatesBest = Vec_IntDup( p->vGates ); p->vGatesBest = Vec_IntDup( p->vGates );
...@@ -281,38 +284,35 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_DnSizePars * pPar ...@@ -281,38 +284,35 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_DnSizePars * pPar
Abc_NtkIncrementTravId( pNtk ); Abc_NtkIncrementTravId( pNtk );
while ( Vec_QueSize(p->vNodeByGain) > 0 ) while ( Vec_QueSize(p->vNodeByGain) > 0 )
{ {
clk = Abc_Clock(); clk = Abc_Clock();
pObj = Abc_NtkObj( p->pNtk, Vec_QuePop(p->vNodeByGain) ); pObj = Abc_NtkObj( p->pNtk, Vec_QuePop(p->vNodeByGain) );
Abc_SclFindWindow( pObj, &vNodes, &vEvals ); Abc_SclFindWindow( pObj, &vNodes, &vEvals );
p->timeCone += Abc_Clock() - clk; p->timeCone += Abc_Clock() - clk;
if ( Abc_SclCheckOverlap( p->pNtk, vNodes ) ) if ( Abc_SclCheckOverlap( p->pNtk, vNodes ) )
nOverlap++, Vec_IntPush( vTryLater, Abc_ObjId(pObj) ); nOverlap++, Vec_IntPush( vTryLater, Abc_ObjId(pObj) );
else else
nChanges += Abc_SclCheckImprovement( p, pObj, vNodes, vEvals ); nChanges += Abc_SclCheckImprovement( p, pObj, vNodes, vEvals, pPars->Notches, pPars->DelayGap );
nAttempt++; nAttempt++;
} }
Abc_NtkForEachObjVec( vTryLater, pNtk, pObj, k ) Abc_NtkForEachObjVec( vTryLater, pNtk, pObj, k )
Vec_QuePush( p->vNodeByGain, Abc_ObjId(pObj) ); Vec_QuePush( p->vNodeByGain, Abc_ObjId(pObj) );
clk = Abc_Clock();
Abc_SclTimeNtkRecompute( p, NULL, NULL, pPars->fUseDept, pPars->DUser ); clk = Abc_Clock();
p->timeTime += Abc_Clock() - clk; Abc_SclTimeNtkRecompute( p, &p->SumArea, &p->MaxDelay, pPars->fUseDept, pPars->DelayUser );
p->timeTime += Abc_Clock() - clk;
p->MaxDelay = Abc_SclReadMaxDelay( p ); p->MaxDelay = Abc_SclReadMaxDelay( p );
if ( pPars->fUseDept && pPars->DUser > 0 && p->MaxDelay < pPars->DUser ) if ( pPars->fUseDept && pPars->DelayUser > 0 && p->MaxDelay < pPars->DelayUser )
p->MaxDelay = pPars->DUser; p->MaxDelay = pPars->DelayUser;
Abc_SclDnsizePrint( p, nRounds++, nAttempt, nOverlap, nChanges, pPars->fVeryVerbose ); Abc_SclDnsizePrint( p, nRounds++, nAttempt, nOverlap, nChanges, pPars->fVeryVerbose );
nAttemptAll += nAttempt; nAttemptAll += nAttempt; nOverlapAll += nOverlap; nChangesAll += nChanges;
nOverlapAll += nOverlap;
nChangesAll += nChanges;
if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit ) if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit )
break; break;
} }
// recompute // recompute
Abc_SclTimeNtkRecompute( p, &p->SumArea, &p->MaxDelay, pPars->fUseDept, pPars->DUser ); // Abc_SclTimeNtkRecompute( p, &p->SumArea, &p->MaxDelay, pPars->fUseDept, pPars->DelayUser );
if ( pPars->fVerbose ) if ( pPars->fVerbose )
Abc_SclDnsizePrint( p, -1, nAttemptAll, nOverlapAll, nChangesAll, 1 ); Abc_SclDnsizePrint( p, -1, nAttemptAll, nOverlapAll, nChangesAll, 1 );
else
printf( " \r" );
if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit ) if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit )
break; break;
if ( nAttemptAll == 0 ) if ( nAttemptAll == 0 )
...@@ -321,6 +321,8 @@ p->timeTime += Abc_Clock() - clk; ...@@ -321,6 +321,8 @@ p->timeTime += Abc_Clock() - clk;
Vec_IntFree( vNodes ); Vec_IntFree( vNodes );
Vec_IntFree( vEvals ); Vec_IntFree( vEvals );
Vec_IntFree( vTryLater ); Vec_IntFree( vTryLater );
if ( !pPars->fVerbose )
printf( " \r" );
// report runtime // report runtime
p->timeTotal = Abc_Clock() - p->timeTotal; p->timeTotal = Abc_Clock() - p->timeTotal;
...@@ -333,8 +335,8 @@ p->timeTime += Abc_Clock() - clk; ...@@ -333,8 +335,8 @@ p->timeTime += Abc_Clock() - clk;
ABC_PRTP( "Runtime: Other ", p->timeOther, p->timeTotal ); ABC_PRTP( "Runtime: Other ", p->timeOther, p->timeTotal );
ABC_PRTP( "Runtime: TOTAL ", p->timeTotal, p->timeTotal ); ABC_PRTP( "Runtime: TOTAL ", p->timeTotal, p->timeTotal );
} }
// if ( pPars->fDumpStats ) if ( pPars->fDumpStats )
// Abc_SclDumpStats( p, "stats2.txt", p->timeTotal ); Abc_SclDumpStats( p, "stats2.txt", p->timeTotal );
if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit ) if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit )
printf( "Gate sizing timed out at %d seconds.\n", pPars->TimeOut ); printf( "Gate sizing timed out at %d seconds.\n", pPars->TimeOut );
......
...@@ -63,39 +63,13 @@ typedef enum // -- timing sense, positive-, negative- or non-unate ...@@ -63,39 +63,13 @@ typedef enum // -- timing sense, positive-, negative- or non-unate
typedef struct SC_SizePars_ SC_SizePars; typedef struct SC_SizePars_ SC_SizePars;
struct SC_SizePars_ struct SC_SizePars_
{ {
int nSteps;
int nRange;
int nRangeF;
int nTimeOut;
int fTryAll;
int fUseWireLoads;
int fPrintCP;
int fVerbose;
int fVeryVerbose;
};
typedef struct SC_UpSizePars_ SC_UpSizePars;
struct SC_UpSizePars_
{
int nIters; int nIters;
int nIterNoChange; int nIterNoChange;
int Window; int Window; // used for upsizing
int Ratio; int Ratio; // used for upsizing
int Notches; int Notches;
int TimeOut; int DelayUser;
int fUseDept; int DelayGap;
int fDumpStats;
int fUseWireLoads;
int fVerbose;
int fVeryVerbose;
};
typedef struct SC_DnSizePars_ SC_DnSizePars;
struct SC_DnSizePars_
{
float DUser;
int nIters;
int nIterNoChange;
int TimeOut; int TimeOut;
int fUseDept; int fUseDept;
int fDumpStats; int fDumpStats;
...@@ -242,6 +216,7 @@ static inline double SC_LibTimeFromPs( SC_Lib * p, double ps ) { return ps ...@@ -242,6 +216,7 @@ static inline double SC_LibTimeFromPs( SC_Lib * p, double ps ) { return ps
#define SC_CellForEachPinIn( p, pPin, i ) Vec_PtrForEachEntryStop( SC_Pin *, p->vPins, pPin, i, p->n_inputs ) #define SC_CellForEachPinIn( p, pPin, i ) Vec_PtrForEachEntryStop( SC_Pin *, p->vPins, pPin, i, p->n_inputs )
#define SC_CellForEachPinOut( p, pPin, i ) Vec_PtrForEachEntryStart( SC_Pin *, p->vPins, pPin, i, p->n_inputs ) #define SC_CellForEachPinOut( p, pPin, i ) Vec_PtrForEachEntryStart( SC_Pin *, p->vPins, pPin, i, p->n_inputs )
#define SC_RingForEachCell( pRing, pCell, i ) for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pNext, i++ ) #define SC_RingForEachCell( pRing, pCell, i ) for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pNext, i++ )
#define SC_RingForEachCellRev( pRing, pCell, i ) for ( i = 0, pCell = pRing; i == 0 || pCell != pRing; pCell = pCell->pPrev, i++ )
#define SC_PinForEachRTiming( p, pRTime, i ) Vec_PtrForEachEntry( SC_Timings *, p->vRTimings, pRTime, i ) #define SC_PinForEachRTiming( p, pRTime, i ) Vec_PtrForEachEntry( SC_Timings *, p->vRTimings, pRTime, i )
...@@ -459,7 +434,7 @@ static inline void Abc_SclLibFree( SC_Lib * p ) ...@@ -459,7 +434,7 @@ static inline void Abc_SclLibFree( SC_Lib * p )
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 fVerbose ); extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose );
/*=== sclDnsize.c ===============================================================*/ /*=== sclDnsize.c ===============================================================*/
extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_DnSizePars * pPars ); extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );
/*=== sclFile.c ===============================================================*/ /*=== sclFile.c ===============================================================*/
extern SC_Lib * Abc_SclRead( char * pFileName ); extern SC_Lib * Abc_SclRead( char * pFileName );
extern void Abc_SclWrite( char * pFileName, SC_Lib * p ); extern void Abc_SclWrite( char * pFileName, SC_Lib * p );
...@@ -471,10 +446,8 @@ extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area ); ...@@ -471,10 +446,8 @@ extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area );
/*=== sclTime.c ===============================================================*/ /*=== sclTime.c ===============================================================*/
extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, int fShowAll, int fShort, int fDumpStats ); extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUseWireLoads, int fShowAll, int fShort, int fDumpStats );
extern void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose ); extern void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose );
/*=== sclSize.c ===============================================================*/
extern void Abc_SclSizingPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * p );
/*=== sclUpsize.c ===============================================================*/ /*=== sclUpsize.c ===============================================================*/
extern void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPars ); extern void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars );
/*=== sclUtil.c ===============================================================*/ /*=== sclUtil.c ===============================================================*/
extern void Abc_SclHashCells( SC_Lib * p ); extern void Abc_SclHashCells( SC_Lib * p );
extern int Abc_SclCellFind( SC_Lib * p, char * pName ); extern int Abc_SclCellFind( SC_Lib * p, char * pName );
......
...@@ -114,7 +114,7 @@ static inline float Abc_SclObjGetSlackF( SC_Man * p, Abc_Obj_t * pObj, float ...@@ -114,7 +114,7 @@ static inline float Abc_SclObjGetSlackF( SC_Man * p, Abc_Obj_t * pObj, float
static inline float Abc_SclObjSlack( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlack[Abc_ObjId(pObj)]; } static inline float Abc_SclObjSlack( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlack[Abc_ObjId(pObj)]; }
static inline void Abc_SclObjDupFanin( SC_Man * p, Abc_Obj_t * pObj ) { assert( Abc_ObjIsCo(pObj) ); *Abc_SclObjTime(p, pObj) = *Abc_SclObjTime(p, Abc_ObjFanin0(pObj)); } static inline void Abc_SclObjDupFanin( SC_Man * p, Abc_Obj_t * pObj ) { assert( Abc_ObjIsCo(pObj) ); *Abc_SclObjTime(p, pObj) = *Abc_SclObjTime(p, Abc_ObjFanin0(pObj)); }
static inline float Abc_SclObjGain( SC_Man * p, Abc_Obj_t * pObj ) { return (Abc_SclObjTime2(p, pObj)->rise - Abc_SclObjTime(p, pObj)->rise) + (Abc_SclObjTime2(p, pObj)->fall - Abc_SclObjTime(p, pObj)->fall); } static inline float Abc_SclObjGain( SC_Man * p, Abc_Obj_t * pObj ) { return 0.5*((Abc_SclObjTime2(p, pObj)->rise - Abc_SclObjTime(p, pObj)->rise) + (Abc_SclObjTime2(p, pObj)->fall - Abc_SclObjTime(p, pObj)->fall)); }
static inline int Abc_SclObjLegal( SC_Man * p, Abc_Obj_t * pObj, float D ) { return Abc_SclObjTime(p, pObj)->rise <= Abc_SclObjTime2(p, pObj)->rise + Abc_SclObjGetSlackR(p, pObj, D) && Abc_SclObjTime(p, pObj)->fall <= Abc_SclObjTime2(p, pObj)->fall + Abc_SclObjGetSlackF(p, pObj, D); } static inline int Abc_SclObjLegal( SC_Man * p, Abc_Obj_t * pObj, float D ) { return Abc_SclObjTime(p, pObj)->rise <= Abc_SclObjTime2(p, pObj)->rise + Abc_SclObjGetSlackR(p, pObj, D) && Abc_SclObjTime(p, pObj)->fall <= Abc_SclObjTime2(p, pObj)->fall + Abc_SclObjGetSlackF(p, pObj, 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); }
......
...@@ -108,18 +108,19 @@ Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t * ...@@ -108,18 +108,19 @@ Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t *
***********************************************************************/ ***********************************************************************/
static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise, int Length, float maxDelay ) static inline void Abc_SclTimeNodePrint( SC_Man * p, Abc_Obj_t * pObj, int fRise, int Length, float maxDelay )
{ {
printf( "%7d : ", Abc_ObjId(pObj) ); printf( "%6d : ", Abc_ObjId(pObj) );
printf( "%d ", Abc_ObjFaninNum(pObj) ); printf( "%d ", Abc_ObjFaninNum(pObj) );
printf( "%2d ", Abc_ObjFanoutNum(pObj) ); printf( "%2d ", Abc_ObjFanoutNum(pObj) );
printf( "%-*s ", Length, Abc_ObjIsPi(pObj) ? "pi" : Abc_SclObjCell(p, pObj)->pName ); printf( "%-*s ", Length, Abc_ObjIsNode(pObj) ? Abc_SclObjCell(p, pObj)->pName : "pi" );
if ( fRise >= 0 ) if ( fRise >= 0 )
printf( "(%s) ", fRise ? "rise" : "fall" ); printf( "(%s) ", fRise ? "rise" : "fall" );
printf( "delay = (" ); printf( "A =%7.2f ", Abc_ObjIsNode(pObj) ? Abc_SclObjCell(p, pObj)->area : 0.0 );
printf( "%8.2f ps ", Abc_SclObjTimePs(p, pObj, 1) ); printf( "D = (" );
printf( "%8.2f ps ) ", Abc_SclObjTimePs(p, pObj, 0) ); printf( "%8.2f ps", Abc_SclObjTimePs(p, pObj, 1) );
printf( "load =%7.2f ff ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) ); printf( "%8.2f ps ) ", Abc_SclObjTimePs(p, pObj, 0) );
printf( "slew =%7.2f ps ", Abc_SclObjSlewPs(p, pObj, fRise >= 0 ? fRise : 0 ) ); printf( "L =%7.2f ff ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) );
printf( "slack =%6.2f ps", Abc_SclObjSlack(p, pObj) ); printf( "S =%7.2f ps ", Abc_SclObjSlewPs(p, pObj, fRise >= 0 ? fRise : 0 ) );
printf( "SL =%6.2f ps", Abc_SclObjSlack(p, pObj) );
printf( "\n" ); printf( "\n" );
} }
void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fShort ) void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fShort )
...@@ -128,10 +129,10 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fShort ) ...@@ -128,10 +129,10 @@ void Abc_SclTimeNtkPrint( SC_Man * p, int fShowAll, int fShort )
Abc_Obj_t * pObj, * pPivot = Abc_SclFindCriticalCo( p, &fRise ); Abc_Obj_t * pObj, * pPivot = Abc_SclFindCriticalCo( p, &fRise );
float maxDelay = Abc_SclObjTimePs(p, pPivot, fRise); float maxDelay = Abc_SclObjTimePs(p, pPivot, fRise);
printf( "WireLoad model = \"%s\". ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" ); printf( "WireLoad model = \"%s\". ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" );
printf( "Gates = %d. ", Abc_NtkNodeNum(p->pNtk) ); printf( "Gates = %6d. ", Abc_NtkNodeNum(p->pNtk) );
printf( "Area = %.2f. ", Abc_SclGetTotalArea( p ) ); printf( "Area = %12.2f. ", Abc_SclGetTotalArea( p ) );
printf( "Critical delay = %.2f ps\n", maxDelay ); printf( "Critical delay = %8.2f ps\n", maxDelay );
if ( fShort ) if ( fShort )
return; return;
...@@ -519,7 +520,7 @@ int Abc_SclHasBufferFanout( Abc_Obj_t * pObj ) ...@@ -519,7 +520,7 @@ int Abc_SclHasBufferFanout( Abc_Obj_t * pObj )
return 1; return 1;
return 0; return 0;
} }
void Abc_Scl_PrintBuffers( SC_Man * p, Abc_Obj_t * pObj, int nOffset ) void Abc_SclPrintBuffersInt( SC_Man * p, Abc_Obj_t * pObj, int nOffset )
{ {
// SC_Cell_t * pCell = Abc_SclObjCell(p, pObj); // SC_Cell_t * pCell = Abc_SclObjCell(p, pObj);
Abc_Obj_t * pFanout; Abc_Obj_t * pFanout;
...@@ -541,7 +542,7 @@ void Abc_Scl_PrintBuffers( SC_Man * p, Abc_Obj_t * pObj, int nOffset ) ...@@ -541,7 +542,7 @@ void Abc_Scl_PrintBuffers( SC_Man * p, Abc_Obj_t * pObj, int nOffset )
printf( "\n" ); printf( "\n" );
Abc_ObjForEachFanout( pObj, pFanout, i ) Abc_ObjForEachFanout( pObj, pFanout, i )
if ( Abc_ObjIsBuffer(pFanout) ) if ( Abc_ObjIsBuffer(pFanout) )
Abc_Scl_PrintBuffers( p, pFanout, nOffset + 1 ); Abc_SclPrintBuffersInt( p, pFanout, nOffset + 1 );
} }
void Abc_SclPrintBufferTrees( SC_Man * p, Abc_Ntk_t * pNtk ) void Abc_SclPrintBufferTrees( SC_Man * p, Abc_Ntk_t * pNtk )
{ {
...@@ -549,7 +550,7 @@ void Abc_SclPrintBufferTrees( SC_Man * p, Abc_Ntk_t * pNtk ) ...@@ -549,7 +550,7 @@ void Abc_SclPrintBufferTrees( SC_Man * p, Abc_Ntk_t * pNtk )
int i; int i;
Abc_NtkForEachObj( pNtk, pObj, i ) Abc_NtkForEachObj( pNtk, pObj, i )
if ( Abc_ObjIsBuffer(pObj) && Abc_SclHasBufferFanout(pObj) ) if ( Abc_ObjIsBuffer(pObj) && Abc_SclHasBufferFanout(pObj) )
Abc_Scl_PrintBuffers( p, pObj, 0 ), printf( "\n" ); Abc_SclPrintBuffersInt( p, pObj, 0 ), printf( "\n" );
} }
void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose ) void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose )
{ {
......
...@@ -194,16 +194,17 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath ) ...@@ -194,16 +194,17 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Vec_Int_t * Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvEvals ) void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int_t ** pvEvals )
{ {
Abc_Ntk_t * p = Abc_ObjNtk(pPivot); Abc_Ntk_t * p = Abc_ObjNtk(pPivot);
Abc_Obj_t * pObj, * pNext, * pNext2; Abc_Obj_t * pObj, * pNext, * pNext2;
Vec_Int_t * vNodes; Vec_Int_t * vNodes = *pvNodes;
Vec_Int_t * vEvals = *pvEvals;
int i, k; int i, k;
assert( Abc_ObjIsNode(pPivot) ); assert( Abc_ObjIsNode(pPivot) );
assert( pPivot->fMarkA ); assert( pPivot->fMarkA );
// collect fanins, node, and fanouts // collect fanins, node, and fanouts
vNodes = Vec_IntAlloc( 16 ); Vec_IntClear( vNodes );
Abc_ObjForEachFanin( pPivot, pNext, i ) Abc_ObjForEachFanin( pPivot, pNext, i )
if ( Abc_ObjIsNode(pNext) && Abc_ObjFaninNum(pNext) > 0 ) if ( Abc_ObjIsNode(pNext) && Abc_ObjFaninNum(pNext) > 0 )
Vec_IntPush( vNodes, Abc_ObjId(pNext) ); Vec_IntPush( vNodes, Abc_ObjId(pNext) );
...@@ -224,21 +225,20 @@ Vec_Int_t * Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvEvals ) ...@@ -224,21 +225,20 @@ Vec_Int_t * Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvEvals )
pObj->fMarkB = 1; pObj->fMarkB = 1;
} }
// collect nodes visible from the critical paths // collect nodes visible from the critical paths
*pvEvals = Vec_IntAlloc( 10 ); Vec_IntClear( vEvals );
Abc_NtkForEachObjVec( vNodes, p, pObj, i ) Abc_NtkForEachObjVec( vNodes, p, pObj, i )
Abc_ObjForEachFanout( pObj, pNext, k ) Abc_ObjForEachFanout( pObj, pNext, k )
if ( pNext->fMarkA && !pNext->fMarkB ) if ( pNext->fMarkA && !pNext->fMarkB )
// if ( !pNext->fMarkB ) // if ( !pNext->fMarkB )
{ {
assert( pObj->fMarkB ); assert( pObj->fMarkB );
Vec_IntPush( *pvEvals, Abc_ObjId(pObj) ); Vec_IntPush( vEvals, Abc_ObjId(pObj) );
break; break;
} }
assert( Vec_IntSize(*pvEvals) > 0 ); assert( Vec_IntSize(vEvals) > 0 );
// label nodes // label nodes
Abc_NtkForEachObjVec( vNodes, p, pObj, i ) Abc_NtkForEachObjVec( vNodes, p, pObj, i )
pObj->fMarkB = 0; pObj->fMarkB = 0;
return vNodes;
} }
...@@ -253,7 +253,7 @@ Vec_Int_t * Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvEvals ) ...@@ -253,7 +253,7 @@ Vec_Int_t * Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvEvals )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notches, int iIter ) int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notches, int iIter, int DelayGap )
{ {
SC_Cell * pCellOld, * pCellNew; SC_Cell * pCellOld, * pCellNew;
Vec_Int_t * vRecalcs, * vEvals; Vec_Int_t * vRecalcs, * vEvals;
...@@ -262,6 +262,8 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch ...@@ -262,6 +262,8 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
int i, k, n, gateBest, Limit, iIterLast; int i, k, n, gateBest, Limit, iIterLast;
// compute savings due to upsizing each node // compute savings due to upsizing each node
vRecalcs = Vec_IntAlloc( 100 );
vEvals = Vec_IntAlloc( 100 );
Vec_QueClear( p->vNodeByGain ); Vec_QueClear( p->vNodeByGain );
Abc_NtkForEachObjVec( vPathNodes, p->pNtk, pObj, i ) Abc_NtkForEachObjVec( vPathNodes, p->pNtk, pObj, i )
{ {
...@@ -269,7 +271,7 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch ...@@ -269,7 +271,7 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
if ( iIterLast >= 0 && iIterLast + 10 > iIter ) if ( iIterLast >= 0 && iIterLast + 10 > iIter )
continue; continue;
// compute nodes to recalculate timing and nodes to evaluate afterwards // compute nodes to recalculate timing and nodes to evaluate afterwards
vRecalcs = Abc_SclFindNodesToUpdate( pObj, &vEvals ); Abc_SclFindNodesToUpdate( pObj, &vRecalcs, &vEvals );
assert( Vec_IntSize(vEvals) > 0 ); assert( Vec_IntSize(vEvals) > 0 );
//printf( "%d -> %d\n", Vec_IntSize(vRecalcs), Vec_IntSize(vEvals) ); //printf( "%d -> %d\n", Vec_IntSize(vRecalcs), Vec_IntSize(vEvals) );
// save old gate, timing, fanin load // save old gate, timing, fanin load
...@@ -278,7 +280,7 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch ...@@ -278,7 +280,7 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
Abc_SclLoadStore( p, pObj ); Abc_SclLoadStore( p, pObj );
// try different gate sizes for this node // try different gate sizes for this node
gateBest = -1; gateBest = -1;
dGainBest = 0.0; dGainBest = -SC_LibTimeFromPs(p->pLib, (float)DelayGap);
SC_RingForEachCell( pCellOld, pCellNew, k ) SC_RingForEachCell( pCellOld, pCellNew, k )
{ {
if ( pCellNew == pCellOld ) if ( pCellNew == pCellOld )
...@@ -316,15 +318,14 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch ...@@ -316,15 +318,14 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
// put back old cell and timing // put back old cell and timing
Abc_SclObjSetCell( p, pObj, pCellOld ); Abc_SclObjSetCell( p, pObj, pCellOld );
Abc_SclConeRestore( p, vRecalcs ); Abc_SclConeRestore( p, vRecalcs );
// cleanup
Vec_IntFree( vRecalcs );
Vec_IntFree( vEvals );
} }
if ( Vec_QueSize(p->vNodeByGain) < 3 ) Vec_IntFree( vRecalcs );
Vec_IntFree( vEvals );
if ( Vec_QueSize(p->vNodeByGain) == 0 )
return 0; return 0;
Limit = Abc_MinInt( Vec_QueSize(p->vNodeByGain), (int)(0.01 * Ratio * Vec_IntSize(vPathNodes)) + 1 ); Limit = Abc_MinInt( Vec_QueSize(p->vNodeByGain), Abc_MaxInt((int)(0.01 * Ratio * Vec_IntSize(vPathNodes)), 1) );
//printf( "\nSelecting %d out of %d\n", Limit, Vec_QueSize(p->vNodeByGain) ); //printf( "\nSelecting %d out of %d\n", Limit, Vec_QueSize(p->vNodeByGain) );
for ( i = 0; i < Limit; i++ ) for ( i = 0; i < Limit; i++ )
{ {
// get the object // get the object
...@@ -334,8 +335,8 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch ...@@ -334,8 +335,8 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
pCellOld = Abc_SclObjCell( p, pObj ); pCellOld = Abc_SclObjCell( p, pObj );
pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) ); pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) );
assert( pCellNew != NULL ); assert( pCellNew != NULL );
// printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName ); //printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName );
// printf( "gain is %f\n", Vec_FltEntry(p->vNode2Gain, Abc_ObjId(pObj)) ); //printf( "gain is %f\n", Vec_FltEntry(p->vNode2Gain, Abc_ObjId(pObj)) );
// update gate // update gate
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew ); Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
p->SumArea += pCellNew->area - pCellOld->area; p->SumArea += pCellNew->area - pCellOld->area;
...@@ -439,7 +440,7 @@ void Abc_SclUpsizePrint( SC_Man * p, int Iter, int win, int nPathPos, int nPathN ...@@ -439,7 +440,7 @@ void Abc_SclUpsizePrint( SC_Man * p, int Iter, int win, int nPathPos, int nPathN
printf( "TFO:%6d. ", nTFOs ); printf( "TFO:%6d. ", nTFOs );
printf( "A: " ); printf( "A: " );
printf( "%.2f ", p->SumArea ); printf( "%.2f ", p->SumArea );
printf( "(%+5.1f %%) ", 100.0 * (p->SumArea - p->SumArea0)/ p->SumArea0 ); printf( "(%+5.1f %%) ", 100.0 * (p->SumArea - p->SumArea0)/ p->SumArea0 );
printf( "D: " ); printf( "D: " );
printf( "%.2f ps ", SC_LibTimePs(p->pLib, p->MaxDelay) ); printf( "%.2f ps ", SC_LibTimePs(p->pLib, p->MaxDelay) );
printf( "(%+5.1f %%) ", 100.0 * (p->MaxDelay - p->MaxDelay0)/ p->MaxDelay0 ); printf( "(%+5.1f %%) ", 100.0 * (p->MaxDelay - p->MaxDelay0)/ p->MaxDelay0 );
...@@ -461,7 +462,7 @@ void Abc_SclUpsizePrint( SC_Man * p, int Iter, int win, int nPathPos, int nPathN ...@@ -461,7 +462,7 @@ void Abc_SclUpsizePrint( SC_Man * p, int Iter, int win, int nPathPos, int nPathN
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPars ) void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars )
{ {
SC_Man * p; SC_Man * p;
Vec_Int_t * vPathPos = NULL; // critical POs Vec_Int_t * vPathPos = NULL; // critical POs
...@@ -473,12 +474,14 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar ...@@ -473,12 +474,14 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar
if ( pPars->fVerbose ) if ( pPars->fVerbose )
{ {
printf( "Upsizing parameters: " ); printf( "Parameters: " );
printf( "Iters =%5d. ", pPars->nIters ); printf( "Iters =%5d. ", pPars->nIters );
printf( "Time win =%3d %%. ", pPars->Window ); printf( "Time win =%3d %%. ", pPars->Window );
printf( "Update ratio =%3d %%. ", pPars->Ratio ); printf( "Update ratio =%3d %%. ", pPars->Ratio );
printf( "UseDept =%2d. ", pPars->fUseDept ); printf( "UseDept =%2d. ", pPars->fUseDept );
printf( "UseWL =%2d. ", pPars->fUseWireLoads ); printf( "UseWL =%2d. ", pPars->fUseWireLoads );
printf( "Target =%5d ps. ", pPars->DelayUser );
printf( "DelayGap =%3d ps. ", pPars->DelayGap );
printf( "Timeout =%4d sec", pPars->TimeOut ); printf( "Timeout =%4d sec", pPars->TimeOut );
printf( "\n" ); printf( "\n" );
} }
...@@ -504,7 +507,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar ...@@ -504,7 +507,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar
// selectively upsize the nodes // selectively upsize the nodes
clk = Abc_Clock(); clk = Abc_Clock();
nUpsizes = Abc_SclFindUpsizes( p, vPathNodes, pPars->Ratio, pPars->Notches, i ); nUpsizes = Abc_SclFindUpsizes( p, vPathNodes, pPars->Ratio, pPars->Notches, i, pPars->DelayGap );
p->timeSize += Abc_Clock() - clk; p->timeSize += Abc_Clock() - clk;
// unmark critical path // unmark critical path
...@@ -545,13 +548,6 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar ...@@ -545,13 +548,6 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar
} }
else else
nFramesNoChange++; nFramesNoChange++;
if ( nFramesNoChange > pPars->nIterNoChange )
{
Vec_IntFree( vPathPos );
Vec_IntFree( vPathNodes );
Vec_IntFree( vTFO );
break;
}
// report and cleanup // report and cleanup
Abc_SclUpsizePrint( p, i, win, Vec_IntSize(vPathPos), Vec_IntSize(vPathNodes), nUpsizes, Vec_IntSize(vTFO), pPars->fVeryVerbose || (pPars->fVerbose && nFramesNoChange == 0) ); //|| (i == nIters-1) ); Abc_SclUpsizePrint( p, i, win, Vec_IntSize(vPathPos), Vec_IntSize(vPathNodes), nUpsizes, Vec_IntSize(vTFO), pPars->fVeryVerbose || (pPars->fVerbose && nFramesNoChange == 0) ); //|| (i == nIters-1) );
...@@ -565,6 +561,12 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar ...@@ -565,6 +561,12 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar
// check timeout // check timeout
if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit ) if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit )
break; break;
// check no change
if ( nFramesNoChange > pPars->nIterNoChange )
break;
// check best delay
if ( p->BestDelay <= SC_LibTimeFromPs(p->pLib, (float)pPars->DelayUser) )
break;
} }
// update for best gates and recompute timing // update for best gates and recompute timing
ABC_SWAP( Vec_Int_t *, p->vGatesBest, p->vGates ); ABC_SWAP( Vec_Int_t *, p->vGatesBest, p->vGates );
......
...@@ -335,6 +335,8 @@ void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerb ...@@ -335,6 +335,8 @@ void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerb
Abc_NtkForEachNode1( p, pObj, i ) Abc_NtkForEachNode1( p, pObj, i )
{ {
gateId = Vec_IntEntry( vGates, i ); gateId = Vec_IntEntry( vGates, i );
// if ( SC_LibCell(pLib, gateId)->n_outputs > 1 )
// continue;
assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) ); assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) );
gateId = Vec_IntEntry( vMinCells, gateId ); gateId = Vec_IntEntry( vMinCells, gateId );
assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) ); assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) );
......
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