From a9afe7e8b7392242446e562f97dc13698005c682 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 21 Jul 2013 14:56:30 -0700 Subject: Improvements to post-mapping re-sizing. --- src/base/io/ioWriteBlif.c | 30 ++++++++-------- src/map/scl/scl.c | 92 +++++++++++++++++++++++++++++++++++------------ src/map/scl/sclDnsize.c | 56 +++++++++++++++-------------- src/map/scl/sclInt.h | 41 ++++----------------- src/map/scl/sclMan.h | 2 +- src/map/scl/sclTime.c | 37 +++++++++---------- src/map/scl/sclUpsize.c | 60 ++++++++++++++++--------------- src/map/scl/sclUtil.c | 2 ++ 8 files changed, 175 insertions(+), 145 deletions(-) diff --git a/src/base/io/ioWriteBlif.c b/src/base/io/ioWriteBlif.c index 9ed2becb..a455dc76 100644 --- a/src/base/io/ioWriteBlif.c +++ b/src/base/io/ioWriteBlif.c @@ -718,24 +718,26 @@ void Io_WriteTimingInfo( FILE * pFile, Abc_Ntk_t * pNtk ) pTimeDef = Abc_NtkReadDefaultInputDrive( pNtk ); if ( pTimeDef->Rise != 0.0 || pTimeDef->Fall != 0.0 ) fprintf( pFile, ".default_input_drive %g %g\n", pTimeDef->Rise, pTimeDef->Fall ); - Abc_NtkForEachPi( pNtk, pNode, i ) - { - pTime = Abc_NodeReadInputDrive( pNtk, i ); - if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall ) - continue; - fprintf( pFile, ".input_drive %s %g %g\n", Abc_ObjName(Abc_ObjFanout0(pNode)), pTime->Rise, pTime->Fall ); - } + if ( Abc_NodeReadInputDrive( pNtk, 0 ) ) + Abc_NtkForEachPi( pNtk, pNode, i ) + { + pTime = Abc_NodeReadInputDrive( pNtk, i ); + if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall ) + continue; + fprintf( pFile, ".input_drive %s %g %g\n", Abc_ObjName(Abc_ObjFanout0(pNode)), pTime->Rise, pTime->Fall ); + } pTimeDef = Abc_NtkReadDefaultOutputLoad( pNtk ); if ( pTimeDef->Rise != 0.0 || pTimeDef->Fall != 0.0 ) fprintf( pFile, ".default_output_load %g %g\n", pTimeDef->Rise, pTimeDef->Fall ); - Abc_NtkForEachPo( pNtk, pNode, i ) - { - pTime = Abc_NodeReadOutputLoad( pNtk, i ); - if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall ) - continue; - fprintf( pFile, ".output_load %s %g %g\n", Abc_ObjName(Abc_ObjFanin0(pNode)), pTime->Rise, pTime->Fall ); - } + if ( Abc_NodeReadOutputLoad( pNtk, 0 ) ) + Abc_NtkForEachPo( pNtk, pNode, i ) + { + pTime = Abc_NodeReadOutputLoad( pNtk, i ); + if ( pTime->Rise == pTimeDef->Rise && pTime->Fall == pTimeDef->Fall ) + continue; + fprintf( pFile, ".output_load %s %g %g\n", Abc_ObjName(Abc_ObjFanin0(pNode)), pTime->Rise, pTime->Fall ); + } fprintf( pFile, "\n" ); } diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index fed62f2b..d6232d2f 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -580,15 +580,17 @@ usage: ***********************************************************************/ 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); int c; - memset( pPars, 0, sizeof(SC_UpSizePars) ); + memset( pPars, 0, sizeof(SC_SizePars) ); pPars->nIters = 1000; pPars->nIterNoChange = 50; pPars->Window = 2; pPars->Ratio = 10; - pPars->Notches = 20; + pPars->Notches = 1000; + pPars->DelayUser = 0; + pPars->DelayGap = 0; pPars->TimeOut = 0; pPars->fUseDept = 1; pPars->fUseWireLoads = 1; @@ -596,7 +598,7 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv ) pPars->fVerbose = 0; pPars->fVeryVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "IJWRNTcsdvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "IJWRNDGTcsdvwh" ) ) != EOF ) { switch ( c ) { @@ -655,6 +657,26 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv ) 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': if ( globalUtilOptind >= argc ) { @@ -713,13 +735,15 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv ) return 0; 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-I : the number of upsizing iterations to perform [default = %d]\n", pPars->nIters ); fprintf( pAbc->Err, "\t-J : the number of iterations without improvement to stop [default = %d]\n", pPars->nIterNoChange ); fprintf( pAbc->Err, "\t-W : delay window (in percent) of near-critical COs [default = %d]\n", pPars->Window ); fprintf( pAbc->Err, "\t-R : ratio of critical nodes (in percent) to update [default = %d]\n", pPars->Ratio ); fprintf( pAbc->Err, "\t-N : limit on discrete upsizing steps at a node [default = %d]\n", pPars->Notches ); + fprintf( pAbc->Err, "\t-D : delay target set by the user, in picoseconds [default = %d]\n", pPars->DelayUser ); + fprintf( pAbc->Err, "\t-G : delay gap during updating, in picoseconds [default = %d]\n", pPars->DelayGap ); fprintf( pAbc->Err, "\t-T : 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-s : toggle using slack based on departure times [default = %s]\n", pPars->fUseDept? "yes": "no" ); @@ -743,13 +767,15 @@ usage: ***********************************************************************/ 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); int c; - memset( pPars, 0, sizeof(SC_DnSizePars) ); - pPars->DUser = 0; + memset( pPars, 0, sizeof(SC_SizePars) ); pPars->nIters = 5; pPars->nIterNoChange = 50; + pPars->Notches = 1000; + pPars->DelayUser = 0; + pPars->DelayGap = 1000; pPars->TimeOut = 0; pPars->fUseDept = 1; pPars->fUseWireLoads = 1; @@ -757,21 +783,10 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv ) pPars->fVerbose = 0; pPars->fVeryVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "DIJTcsdvwh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "IJNDGTcsdvwh" ) ) != EOF ) { 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': if ( globalUtilOptind >= argc ) { @@ -794,6 +809,37 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv ) if ( pPars->nIterNoChange < 0 ) goto usage; 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': if ( globalUtilOptind >= argc ) { @@ -852,11 +898,13 @@ int Scl_CommandDnsize( Abc_Frame_t * pAbc, int argc, char **argv ) return 0; 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-D : the target max delay after downsizing in picosecs [default = %.2f]\n", pPars->DUser ); fprintf( pAbc->Err, "\t-I : the number of upsizing iterations to perform [default = %d]\n", pPars->nIters ); fprintf( pAbc->Err, "\t-J : the number of iterations without improvement to stop [default = %d]\n", pPars->nIterNoChange ); + fprintf( pAbc->Err, "\t-N : limit on discrete upsizing steps at a node [default = %d]\n", pPars->Notches ); + fprintf( pAbc->Err, "\t-D : delay target set by the user, in picoseconds [default = %d]\n", pPars->DelayUser ); + fprintf( pAbc->Err, "\t-G : delay gap during updating, in picoseconds [default = %d]\n", pPars->DelayGap ); fprintf( pAbc->Err, "\t-T : 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-s : toggle using slack based on departure times [default = %s]\n", pPars->fUseDept? "yes": "no" ); diff --git a/src/map/scl/sclDnsize.c b/src/map/scl/sclDnsize.c index b0a7c49d..3df64e80 100644 --- a/src/map/scl/sclDnsize.c +++ b/src/map/scl/sclDnsize.c @@ -99,7 +99,7 @@ void Abc_SclFindWindow( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int_t ** p 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; SC_Cell * pCellOld, * pCellNew; @@ -114,11 +114,13 @@ clk = Abc_Clock(); Abc_SclLoadStore( p, pObj ); // try different gate sizes for this node gateBest = -1; - dGainBest = -ABC_INFINITY; //0.0; - SC_RingForEachCell( pCellOld, pCellNew, i ) + dGainBest = -SC_LibTimeFromPs(p->pLib, (float)DelayGap); + SC_RingForEachCellRev( pCellOld, pCellNew, i ) { if ( pCellNew->area >= pCellOld->area ) continue; + if ( i > Notches ) + break; // set new cell Abc_SclObjSetCell( p, pObj, pCellNew ); Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew ); @@ -240,7 +242,7 @@ void Abc_SclDnsizePrint( SC_Man * p, int Iter, int nAttempts, int nOverlaps, int 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; Abc_Obj_t * pObj; @@ -250,17 +252,18 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_DnSizePars * pPar if ( pPars->fVerbose ) { - printf( "Downsizing parameters: " ); - printf( "Delay =%8.2f ps. ", pPars->DUser ); - printf( "Iters =%5d. ", pPars->nIters ); - printf( "UseDept =%2d. ", pPars->fUseDept ); - printf( "UseWL =%2d. ", pPars->fUseWireLoads ); - printf( "Timeout =%4d sec", pPars->TimeOut ); + printf( "Parameters: " ); + printf( "Iters =%5d. ", pPars->nIters ); + printf( "UseDept =%2d. ", pPars->fUseDept ); + printf( "UseWL =%2d. ", pPars->fUseWireLoads ); + printf( "Target =%5d ps. ", pPars->DelayUser ); + printf( "DelayGap =%3d ps. ", pPars->DelayGap ); + printf( "Timeout =%4d sec", pPars->TimeOut ); printf( "\n" ); } // 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(); assert( p->vGatesBest == NULL ); p->vGatesBest = Vec_IntDup( p->vGates ); @@ -281,38 +284,35 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_DnSizePars * pPar Abc_NtkIncrementTravId( pNtk ); while ( Vec_QueSize(p->vNodeByGain) > 0 ) { -clk = Abc_Clock(); + clk = Abc_Clock(); pObj = Abc_NtkObj( p->pNtk, Vec_QuePop(p->vNodeByGain) ); Abc_SclFindWindow( pObj, &vNodes, &vEvals ); -p->timeCone += Abc_Clock() - clk; + p->timeCone += Abc_Clock() - clk; if ( Abc_SclCheckOverlap( p->pNtk, vNodes ) ) nOverlap++, Vec_IntPush( vTryLater, Abc_ObjId(pObj) ); else - nChanges += Abc_SclCheckImprovement( p, pObj, vNodes, vEvals ); + nChanges += Abc_SclCheckImprovement( p, pObj, vNodes, vEvals, pPars->Notches, pPars->DelayGap ); nAttempt++; } Abc_NtkForEachObjVec( vTryLater, pNtk, pObj, k ) Vec_QuePush( p->vNodeByGain, Abc_ObjId(pObj) ); -clk = Abc_Clock(); - Abc_SclTimeNtkRecompute( p, NULL, NULL, pPars->fUseDept, pPars->DUser ); -p->timeTime += Abc_Clock() - clk; + + clk = Abc_Clock(); + Abc_SclTimeNtkRecompute( p, &p->SumArea, &p->MaxDelay, pPars->fUseDept, pPars->DelayUser ); + p->timeTime += Abc_Clock() - clk; p->MaxDelay = Abc_SclReadMaxDelay( p ); - if ( pPars->fUseDept && pPars->DUser > 0 && p->MaxDelay < pPars->DUser ) - p->MaxDelay = pPars->DUser; + if ( pPars->fUseDept && pPars->DelayUser > 0 && p->MaxDelay < pPars->DelayUser ) + p->MaxDelay = pPars->DelayUser; Abc_SclDnsizePrint( p, nRounds++, nAttempt, nOverlap, nChanges, pPars->fVeryVerbose ); - nAttemptAll += nAttempt; - nOverlapAll += nOverlap; - nChangesAll += nChanges; + nAttemptAll += nAttempt; nOverlapAll += nOverlap; nChangesAll += nChanges; if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit ) break; } // 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 ) Abc_SclDnsizePrint( p, -1, nAttemptAll, nOverlapAll, nChangesAll, 1 ); - else - printf( " \r" ); if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit ) break; if ( nAttemptAll == 0 ) @@ -321,6 +321,8 @@ p->timeTime += Abc_Clock() - clk; Vec_IntFree( vNodes ); Vec_IntFree( vEvals ); Vec_IntFree( vTryLater ); + if ( !pPars->fVerbose ) + printf( " \r" ); // report runtime p->timeTotal = Abc_Clock() - p->timeTotal; @@ -333,8 +335,8 @@ p->timeTime += Abc_Clock() - clk; ABC_PRTP( "Runtime: Other ", p->timeOther, p->timeTotal ); ABC_PRTP( "Runtime: TOTAL ", p->timeTotal, p->timeTotal ); } -// if ( pPars->fDumpStats ) -// Abc_SclDumpStats( p, "stats2.txt", p->timeTotal ); + if ( pPars->fDumpStats ) + Abc_SclDumpStats( p, "stats2.txt", p->timeTotal ); if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit ) printf( "Gate sizing timed out at %d seconds.\n", pPars->TimeOut ); diff --git a/src/map/scl/sclInt.h b/src/map/scl/sclInt.h index 6aa353da..58a2ca07 100644 --- a/src/map/scl/sclInt.h +++ b/src/map/scl/sclInt.h @@ -62,40 +62,14 @@ typedef enum // -- timing sense, positive-, negative- or non-unate typedef struct SC_SizePars_ 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 nIterNoChange; - int Window; - int Ratio; + int Window; // used for upsizing + int Ratio; // used for upsizing int Notches; - int TimeOut; - int fUseDept; - int fDumpStats; - int fUseWireLoads; - int fVerbose; - int fVeryVerbose; -}; - -typedef struct SC_DnSizePars_ SC_DnSizePars; -struct SC_DnSizePars_ -{ - float DUser; - int nIters; - int nIterNoChange; + int DelayUser; + int DelayGap; int TimeOut; int fUseDept; int fDumpStats; @@ -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_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_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 ) @@ -459,7 +434,7 @@ static inline void Abc_SclLibFree( SC_Lib * p ) extern int Abc_SclCheckNtk( Abc_Ntk_t * p, int fVerbose ); extern Abc_Ntk_t * Abc_SclPerformBuffering( Abc_Ntk_t * p, int Degree, int fVerbose ); /*=== 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 ===============================================================*/ extern SC_Lib * Abc_SclRead( char * pFileName ); extern void Abc_SclWrite( char * pFileName, SC_Lib * p ); @@ -471,10 +446,8 @@ extern SC_WireLoad * Abc_SclFindWireLoadModel( SC_Lib * p, float Area ); /*=== sclTime.c ===============================================================*/ 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 ); -/*=== sclSize.c ===============================================================*/ -extern void Abc_SclSizingPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * p ); /*=== 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 ===============================================================*/ extern void Abc_SclHashCells( SC_Lib * p ); extern int Abc_SclCellFind( SC_Lib * p, char * pName ); diff --git a/src/map/scl/sclMan.h b/src/map/scl/sclMan.h index a6bdd806..54a6022a 100644 --- a/src/map/scl/sclMan.h +++ b/src/map/scl/sclMan.h @@ -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 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 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); } diff --git a/src/map/scl/sclTime.c b/src/map/scl/sclTime.c index 96c9fec9..7d2ddc31 100644 --- a/src/map/scl/sclTime.c +++ b/src/map/scl/sclTime.c @@ -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 ) { - printf( "%7d : ", Abc_ObjId(pObj) ); - printf( "%d ", Abc_ObjFaninNum(pObj) ); - printf( "%2d ", Abc_ObjFanoutNum(pObj) ); - printf( "%-*s ", Length, Abc_ObjIsPi(pObj) ? "pi" : Abc_SclObjCell(p, pObj)->pName ); + printf( "%6d : ", Abc_ObjId(pObj) ); + printf( "%d ", Abc_ObjFaninNum(pObj) ); + printf( "%2d ", Abc_ObjFanoutNum(pObj) ); + printf( "%-*s ", Length, Abc_ObjIsNode(pObj) ? Abc_SclObjCell(p, pObj)->pName : "pi" ); if ( fRise >= 0 ) - printf( "(%s) ", fRise ? "rise" : "fall" ); - printf( "delay = (" ); - printf( "%8.2f ps ", Abc_SclObjTimePs(p, pObj, 1) ); - printf( "%8.2f ps ) ", Abc_SclObjTimePs(p, pObj, 0) ); - printf( "load =%7.2f ff ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) ); - printf( "slew =%7.2f ps ", Abc_SclObjSlewPs(p, pObj, fRise >= 0 ? fRise : 0 ) ); - printf( "slack =%6.2f ps", Abc_SclObjSlack(p, pObj) ); + printf( "(%s) ", fRise ? "rise" : "fall" ); + printf( "A =%7.2f ", Abc_ObjIsNode(pObj) ? Abc_SclObjCell(p, pObj)->area : 0.0 ); + printf( "D = (" ); + printf( "%8.2f ps", Abc_SclObjTimePs(p, pObj, 1) ); + printf( "%8.2f ps ) ", Abc_SclObjTimePs(p, pObj, 0) ); + printf( "L =%7.2f ff ", Abc_SclObjLoadFf(p, pObj, fRise >= 0 ? fRise : 0 ) ); + printf( "S =%7.2f ps ", Abc_SclObjSlewPs(p, pObj, fRise >= 0 ? fRise : 0 ) ); + printf( "SL =%6.2f ps", Abc_SclObjSlack(p, pObj) ); printf( "\n" ); } 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 ); float maxDelay = Abc_SclObjTimePs(p, pPivot, fRise); - printf( "WireLoad model = \"%s\". ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" ); - printf( "Gates = %d. ", Abc_NtkNodeNum(p->pNtk) ); - printf( "Area = %.2f. ", Abc_SclGetTotalArea( p ) ); - printf( "Critical delay = %.2f ps\n", maxDelay ); + printf( "WireLoad model = \"%s\". ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" ); + printf( "Gates = %6d. ", Abc_NtkNodeNum(p->pNtk) ); + printf( "Area = %12.2f. ", Abc_SclGetTotalArea( p ) ); + printf( "Critical delay = %8.2f ps\n", maxDelay ); if ( fShort ) return; @@ -519,7 +520,7 @@ int Abc_SclHasBufferFanout( Abc_Obj_t * pObj ) return 1; 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); Abc_Obj_t * pFanout; @@ -541,7 +542,7 @@ void Abc_Scl_PrintBuffers( SC_Man * p, Abc_Obj_t * pObj, int nOffset ) printf( "\n" ); Abc_ObjForEachFanout( pObj, pFanout, i ) 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 ) { @@ -549,7 +550,7 @@ void Abc_SclPrintBufferTrees( SC_Man * p, Abc_Ntk_t * pNtk ) int i; Abc_NtkForEachObj( pNtk, pObj, i ) 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 ) { diff --git a/src/map/scl/sclUpsize.c b/src/map/scl/sclUpsize.c index ec06d690..c717ec8f 100644 --- a/src/map/scl/sclUpsize.c +++ b/src/map/scl/sclUpsize.c @@ -194,16 +194,17 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath ) 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_Obj_t * pObj, * pNext, * pNext2; - Vec_Int_t * vNodes; + Vec_Int_t * vNodes = *pvNodes; + Vec_Int_t * vEvals = *pvEvals; int i, k; assert( Abc_ObjIsNode(pPivot) ); assert( pPivot->fMarkA ); // collect fanins, node, and fanouts - vNodes = Vec_IntAlloc( 16 ); + Vec_IntClear( vNodes ); Abc_ObjForEachFanin( pPivot, pNext, i ) if ( Abc_ObjIsNode(pNext) && Abc_ObjFaninNum(pNext) > 0 ) Vec_IntPush( vNodes, Abc_ObjId(pNext) ); @@ -224,21 +225,20 @@ Vec_Int_t * Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvEvals ) pObj->fMarkB = 1; } // collect nodes visible from the critical paths - *pvEvals = Vec_IntAlloc( 10 ); + Vec_IntClear( vEvals ); Abc_NtkForEachObjVec( vNodes, p, pObj, i ) Abc_ObjForEachFanout( pObj, pNext, k ) if ( pNext->fMarkA && !pNext->fMarkB ) // if ( !pNext->fMarkB ) { assert( pObj->fMarkB ); - Vec_IntPush( *pvEvals, Abc_ObjId(pObj) ); + Vec_IntPush( vEvals, Abc_ObjId(pObj) ); break; } - assert( Vec_IntSize(*pvEvals) > 0 ); + assert( Vec_IntSize(vEvals) > 0 ); // label nodes Abc_NtkForEachObjVec( vNodes, p, pObj, i ) pObj->fMarkB = 0; - return vNodes; } @@ -253,7 +253,7 @@ Vec_Int_t * Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvEvals ) 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; Vec_Int_t * vRecalcs, * vEvals; @@ -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; // compute savings due to upsizing each node + vRecalcs = Vec_IntAlloc( 100 ); + vEvals = Vec_IntAlloc( 100 ); Vec_QueClear( p->vNodeByGain ); 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 if ( iIterLast >= 0 && iIterLast + 10 > iIter ) continue; // 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 ); //printf( "%d -> %d\n", Vec_IntSize(vRecalcs), Vec_IntSize(vEvals) ); // save old gate, timing, fanin load @@ -278,7 +280,7 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch Abc_SclLoadStore( p, pObj ); // try different gate sizes for this node gateBest = -1; - dGainBest = 0.0; + dGainBest = -SC_LibTimeFromPs(p->pLib, (float)DelayGap); SC_RingForEachCell( pCellOld, pCellNew, k ) { if ( pCellNew == pCellOld ) @@ -316,15 +318,14 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch // put back old cell and timing Abc_SclObjSetCell( p, pObj, pCellOld ); 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; - Limit = Abc_MinInt( Vec_QueSize(p->vNodeByGain), (int)(0.01 * Ratio * Vec_IntSize(vPathNodes)) + 1 ); -//printf( "\nSelecting %d out of %d\n", Limit, Vec_QueSize(p->vNodeByGain) ); + 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) ); for ( i = 0; i < Limit; i++ ) { // get the object @@ -334,8 +335,8 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch pCellOld = Abc_SclObjCell( p, pObj ); pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) ); assert( pCellNew != NULL ); -// printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName ); -// printf( "gain is %f\n", Vec_FltEntry(p->vNode2Gain, Abc_ObjId(pObj)) ); + //printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName ); + //printf( "gain is %f\n", Vec_FltEntry(p->vNode2Gain, Abc_ObjId(pObj)) ); // update gate Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew ); p->SumArea += pCellNew->area - pCellOld->area; @@ -439,7 +440,7 @@ void Abc_SclUpsizePrint( SC_Man * p, int Iter, int win, int nPathPos, int nPathN printf( "TFO:%6d. ", nTFOs ); printf( "A: " ); 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( "%.2f ps ", SC_LibTimePs(p->pLib, p->MaxDelay) ); 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 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; Vec_Int_t * vPathPos = NULL; // critical POs @@ -473,12 +474,14 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar if ( pPars->fVerbose ) { - printf( "Upsizing parameters: " ); + printf( "Parameters: " ); printf( "Iters =%5d. ", pPars->nIters ); printf( "Time win =%3d %%. ", pPars->Window ); printf( "Update ratio =%3d %%. ", pPars->Ratio ); printf( "UseDept =%2d. ", pPars->fUseDept ); printf( "UseWL =%2d. ", pPars->fUseWireLoads ); + printf( "Target =%5d ps. ", pPars->DelayUser ); + printf( "DelayGap =%3d ps. ", pPars->DelayGap ); printf( "Timeout =%4d sec", pPars->TimeOut ); printf( "\n" ); } @@ -504,7 +507,7 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar // selectively upsize the nodes 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; // unmark critical path @@ -545,13 +548,6 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar } else nFramesNoChange++; - if ( nFramesNoChange > pPars->nIterNoChange ) - { - Vec_IntFree( vPathPos ); - Vec_IntFree( vPathNodes ); - Vec_IntFree( vTFO ); - break; - } // 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) ); @@ -565,6 +561,12 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_UpSizePars * pPar // check timeout if ( nRuntimeLimit && Abc_Clock() > nRuntimeLimit ) 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 ABC_SWAP( Vec_Int_t *, p->vGatesBest, p->vGates ); diff --git a/src/map/scl/sclUtil.c b/src/map/scl/sclUtil.c index 284783b9..d535ee66 100644 --- a/src/map/scl/sclUtil.c +++ b/src/map/scl/sclUtil.c @@ -335,6 +335,8 @@ void Abc_SclMinsizePerform( SC_Lib * pLib, Abc_Ntk_t * p, int fUseMax, int fVerb Abc_NtkForEachNode1( p, pObj, i ) { gateId = Vec_IntEntry( vGates, i ); +// if ( SC_LibCell(pLib, gateId)->n_outputs > 1 ) +// continue; assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) ); gateId = Vec_IntEntry( vMinCells, gateId ); assert( gateId >= 0 && gateId < Vec_PtrSize(pLib->vCells) ); -- cgit v1.2.3