From 39d2b28f74cc6323ce613834f6ac292bcdbe3b00 Mon Sep 17 00:00:00 2001 From: Eddie Hung Date: Wed, 6 May 2020 11:15:46 -0700 Subject: [PATCH] &trace to support -W (wire delay) and -w (print path) options --- src/aig/gia/gia.h | 2 +- src/aig/gia/giaIf.c | 2 +- src/aig/gia/giaSpeedup.c | 83 +++++++++++++++++++++++++++++++++++++++- src/base/abci/abc.c | 47 ++++++++++++++++++++--- 4 files changed, 125 insertions(+), 9 deletions(-) diff --git a/src/aig/gia/gia.h b/src/aig/gia/gia.h index ae9835ee7..d293df203 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 89ef9ffc7..7591f2d66 100644 --- a/src/aig/gia/giaIf.c +++ b/src/aig/gia/giaIf.c @@ -2364,7 +2364,7 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars ) { Gia_ManTransferTiming( pNew, p ); pNew->pLutLib = pPars->pLutLib; - Gia_ManDelayTraceLutPrint( pNew, pPars->fVerbose ); + Gia_ManDelayTraceLutPrint( pNew, 1, 0 ); pNew->pLutLib = NULL; Gia_ManTransferTiming( p, pNew ); } diff --git a/src/aig/gia/giaSpeedup.c b/src/aig/gia/giaSpeedup.c index 64405876c..069e16a11 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 @@ -448,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) ) { @@ -478,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++ ) { @@ -490,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 85053e189..e167b4d93 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 : toggles printing critical path [default = %s]\n", fVerbosePath? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; }