diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index ae9835ee7b..d293df2030 100644 --- a/src/aig/gia/gia.h +++ b/src/aig/gia/gia.h @@ -1559,7 +1559,7 @@ extern int Gia_ManIncrSimCheckOver( Gia_Man_t * p, int iLit0, in extern int Gia_ManIncrSimCheckEqual( Gia_Man_t * p, int iLit0, int iLit1 ); /*=== giaSpeedup.c ============================================================*/ extern float Gia_ManDelayTraceLut( Gia_Man_t * p ); -extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ); +extern float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose, int fVerbosePath ); extern Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerbose, int fVeryVerbose ); /*=== giaSplit.c ============================================================*/ extern void Gia_ManComputeOneWinStart( Gia_Man_t * p, int nAnds, int fReverse ); diff --git a/src/aig/gia/giaIf.c b/src/aig/gia/giaIf.c index 37ca6d4b50..7591f2d662 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -2362,9 +2362,11 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars ) // print delay trace if ( pPars->fVerboseTrace ) { + Gia_ManTransferTiming( pNew, p ); pNew->pLutLib = pPars->pLutLib; - Gia_ManDelayTraceLutPrint( pNew, 1 ); + Gia_ManDelayTraceLutPrint( pNew, 1, 0 ); pNew->pLutLib = NULL; + Gia_ManTransferTiming( p, pNew ); } return pNew; } diff --git a/src/aig/gia/giaSpeedup.c b/src/aig/gia/giaSpeedup.c index b9f4f03716..069e16a118 100644 --- a/src/aig/gia/giaSpeedup.c +++ b/src/aig/gia/giaSpeedup.c @@ -20,6 +20,7 @@ #include "gia.h" #include "map/if/if.h" +#include "base/main/main.h" ABC_NAMESPACE_IMPL_START @@ -246,16 +247,24 @@ float Gia_ManDelayTraceLut( Gia_Man_t * p ) // initialize the arrival times Gia_ManTimeStart( p ); - Gia_ManLevelNum( p ); // propagate arrival times if ( p->pManTime ) Tim_ManIncrementTravId( (Tim_Man_t *)p->pManTime ); - Gia_ManForEachObj( p, pObj, i ) + + if ( Gia_ManIsNormalized(p) ) + vObjs = Gia_ManOrderWithBoxes( p ); + else { + vObjs = Vec_IntAlloc( Gia_ManObjNum(p) ); + for (i = 0; i < Gia_ManObjNum(p); i++) + Vec_IntPush( vObjs, i ); + } + Vec_IntForEachEntry( vObjs, iObj, i ) { - if ( !Gia_ObjIsCi(pObj) && !Gia_ObjIsCo(pObj) && !Gia_ObjIsLut(p, i) ) + pObj = Gia_ManObj(p, iObj); + if ( !Gia_ObjIsCi(pObj) && !Gia_ObjIsCo(pObj) && !Gia_ObjIsLut(p, iObj) ) continue; - tArrival = Gia_ObjComputeArrival( p, i, fUseSorting ); + tArrival = Gia_ObjComputeArrival( p, iObj, fUseSorting ); if ( Gia_ObjIsCi(pObj) && p->pManTime ) { tArrival = Tim_ManGetCiArrival( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj) ); @@ -263,7 +272,7 @@ float Gia_ManDelayTraceLut( Gia_Man_t * p ) } if ( Gia_ObjIsCo(pObj) && p->pManTime ) Tim_ManSetCoArrival( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj), tArrival ); - Gia_ObjSetTimeArrival( p, i, tArrival ); + Gia_ObjSetTimeArrival( p, iObj, tArrival ); } // get the latest arrival times @@ -289,8 +298,7 @@ float Gia_ManDelayTraceLut( Gia_Man_t * p ) } // propagate the required times - vObjs = Gia_ManOrderReverse( p ); - Vec_IntForEachEntry( vObjs, iObj, i ) + Vec_IntForEachEntryReverse( vObjs, iObj, i ) { pObj = Gia_ManObj(p, iObj); if ( Gia_ObjIsLut(p, iObj) ) @@ -441,11 +449,14 @@ int Gia_LutVerifyTiming( Gia_Man_t * p ) SeeAlso [] ***********************************************************************/ -float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ) +float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose, int fVerbosePath ) { If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib; int i, Nodes, * pCounters; float tArrival, tDelta, nSteps, Num; + Gia_Obj_t * pObj; + If_LibBox_t * pLibBox; + int iLut, iBox, iDelayTable, nBoxIns, iShift; // get the library if ( pLutLib && pLutLib->LutMax < Gia_ManLutSizeMax(p) ) { @@ -471,10 +482,10 @@ float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ) assert( Num >=0 && Num <= nSteps ); pCounters[(int)Num]++; } + printf( "Max delay = %6.2f. Delay trace using %s model%c\n", tArrival, pLutLib? "LUT library" : "unit-delay", (fVerbose || fVerbosePath ? ':' : '.')); // print the results if ( fVerbose ) { - printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pLutLib? "LUT library" : "unit-delay" ); Nodes = 0; for ( i = 0; i < nSteps; i++ ) { @@ -483,6 +494,81 @@ float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose ) pLutLib? "%":"lev", Nodes, 100.0*Nodes/Gia_ManLutNum(p) ); } } + + if ( fVerbosePath ) + { + pLibBox = Abc_FrameReadLibBox(); + + // find the first critical (latest arriving) CO + pObj = NULL; + Gia_ManForEachCo( p, pObj, i ) + { + if (Gia_ObjTimeArrivalObj( p, pObj ) == tArrival) + break; + } + if ( Gia_ObjIsRo(p, pObj) ) + printf( "%8.2f RO\n", tArrival ); + else if ( Gia_ObjIsPo(p, pObj) ) + printf( "%8.2f PO\n", tArrival ); + else + assert( 0 ); + + // iterate backwards to find the critical fanin (having zero slack) + while ( pObj ) + { + assert( Gia_ObjTimeSlackObj( p, pObj ) == 0 ); + if ( Gia_ObjIsPo(p, pObj) || Gia_ObjIsRo(p, pObj) ) + pObj = Gia_ObjFanin0( pObj ); + else if ( Gia_ObjIsRi(p, pObj) ) + { + tArrival = Gia_ObjTimeArrivalObj( p, pObj ); + printf( "%8.2f RI\n", tArrival ); + break; + } + else if ( Gia_ObjIsLut(p, Gia_ObjId(p, pObj)) ) + { + iLut = Gia_ObjId( p, pObj ); + pObj = NULL; + Gia_LutForEachFaninObj( p, iLut, pObj, i ) + { + if ( Gia_ObjTimeSlackObj( p, pObj ) == 0 ) + break; + } + tArrival = Gia_ObjTimeArrivalObj( p, pObj ); + printf( "%8.2f LUT (K = %d)\n", tArrival, Gia_ObjLutSize(p, iLut)); + } + else if ( Gia_ObjIsCi(pObj) ) + { + iBox = Tim_ManBoxForCi( p->pManTime, Gia_ObjCioId(pObj) ); + if ( iBox == -1 ) + { + printf( "%8.2f PI\n", tArrival ); + break; + } + nBoxIns = Tim_ManBoxInputNum( p->pManTime, iBox ); + iShift = Tim_ManBoxInputFirst( p->pManTime, iBox ); + pObj = NULL; + for ( i = 0; i < nBoxIns; i++ ) + { + pObj = Gia_ManCo( p, iShift + i ); + if ( Gia_ObjTimeSlackObj( p, pObj ) == 0 ) + break; + } + assert( i < nBoxIns ); + + tArrival = Tim_ManGetCoRequired( (Tim_Man_t *)p->pManTime, Gia_ObjCioId(pObj) ); + iDelayTable = Tim_ManBoxDelayTableId(p->pManTime, iBox); + If_Box_t *pIfBox = pLibBox ? If_LibBoxReadBox( pLibBox, iDelayTable ) : NULL; + printf("%8.2f BOX num %5d", tArrival, iBox ); + if ( pIfBox ) + printf( " (%s)\n", pIfBox->pName ); + else + printf( " (id %d)\n", iDelayTable ); + } + else + assert( 0 ); + } + } ABC_FREE( pCounters ); Gia_ManTimeStop( p ); return tArrival; diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 85053e1897..e54eba1c4b 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -40426,11 +40426,15 @@ int Abc_CommandAbc9Trace( Abc_Frame_t * pAbc, int argc, char ** argv ) int c; int fUseLutLib; int fVerbose; + int fVerbosePath; + float WireDelay; // set defaults fUseLutLib = 0; fVerbose = 0; + fVerbosePath = 0; + WireDelay = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "lvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "lvhwW" ) ) != EOF ) { switch ( c ) { @@ -40440,6 +40444,20 @@ int Abc_CommandAbc9Trace( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'v': fVerbose ^= 1; break; + case 'w': + fVerbosePath ^= 1; + break; + case 'W': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-W\" should be followed by a floating point number.\n" ); + goto usage; + } + WireDelay = (float)atof(argv[globalUtilOptind]); + globalUtilOptind++; + if ( WireDelay < 0.0 ) + goto usage; + break; case 'h': goto usage; default: @@ -40448,23 +40466,42 @@ int Abc_CommandAbc9Trace( Abc_Frame_t * pAbc, int argc, char ** argv ) } if ( pAbc->pGia == NULL ) { - Abc_Print( -1, "Abc_CommandAbc9Speedup(): There is no AIG to map.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Trace(): There is no AIG to map.\n" ); return 1; } if ( !Gia_ManHasMapping(pAbc->pGia) ) { - Abc_Print( -1, "Abc_CommandAbc9Speedup(): Mapping of the AIG is not defined.\n" ); + Abc_Print( -1, "Abc_CommandAbc9Trace(): Mapping of the AIG is not defined.\n" ); return 1; } pAbc->pGia->pLutLib = fUseLutLib ? pAbc->pLibLut : NULL; - Gia_ManDelayTraceLutPrint( pAbc->pGia, fVerbose ); + If_LibLut_t * pLutLib = pAbc->pGia->pLutLib; + // add wire delay to LUT library delays + if ( pLutLib && WireDelay > 0 ) + { + int i, k; + for ( i = 0; i <= pLutLib->LutMax; i++ ) + for ( k = 0; k <= i; k++ ) + pLutLib->pLutDelays[i][k] += WireDelay; + } + Gia_ManDelayTraceLutPrint( pAbc->pGia, fVerbose, fVerbosePath ); + // subtract wire delay from LUT library delays + if ( pLutLib && WireDelay > 0 ) + { + int i, k; + for ( i = 0; i <= pLutLib->LutMax; i++ ) + for ( k = 0; k <= i; k++ ) + pLutLib->pLutDelays[i][k] -= WireDelay; + } return 0; usage: Abc_Print( -2, "usage: &trace [-lvh]\n" ); Abc_Print( -2, "\t performs delay trace of LUT-mapped network\n" ); + Abc_Print( -2, "\t-W float : sets wire delay between adjects LUTs [default = %f]\n", WireDelay ); Abc_Print( -2, "\t-l : toggle using unit- or LUT-library-delay model [default = %s]\n", fUseLutLib? "lib": "unit" ); - Abc_Print( -2, "\t-v : toggle printing optimization summary [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-v : toggle printing slack summary [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-w : toggle printing critical path [default = %s]\n", fVerbosePath? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; }