From 2d835aabf0cb0530aeb33aa8e8f2744945b26d2e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 16 Jun 2026 07:46:55 -0700 Subject: [PATCH] Adding command "power" to eval static/dynamic power --- src/map/scl/scl.c | 105 ++++++++++++++++++++++++++++++++++++++- src/map/scl/sclLib.h | 70 ++++++++++++++++++++++++-- src/map/scl/sclLibScl.c | 4 ++ src/map/scl/sclLibUtil.c | 11 +++- src/map/scl/sclLiberty.c | 14 ++++++ src/map/scl/sclSize.c | 87 +++++++++++++++++++++++++++++++- src/map/scl/sclSize.h | 1 + 7 files changed, 285 insertions(+), 7 deletions(-) diff --git a/src/map/scl/scl.c b/src/map/scl/scl.c index b012435f5..f023680e2 100644 --- a/src/map/scl/scl.c +++ b/src/map/scl/scl.c @@ -42,6 +42,7 @@ static int Scl_CommandLeak2Area ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Scl_CommandDumpGen ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Scl_CommandPrintGS ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Scl_CommandStime ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Scl_CommandPower ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Scl_CommandTopo ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Scl_CommandUnBuffer ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Scl_CommandBuffer ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -110,6 +111,7 @@ void Scl_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "SCL mapping", "dump_genlib", Scl_CommandDumpGen, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "print_gs", Scl_CommandPrintGS, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "stime", Scl_CommandStime, 0 ); + Cmd_CommandAdd( pAbc, "SCL mapping", "power", Scl_CommandPower, 0 ); Cmd_CommandAdd( pAbc, "SCL mapping", "topo", Scl_CommandTopo, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "unbuffer", Scl_CommandUnBuffer, 1 ); Cmd_CommandAdd( pAbc, "SCL mapping", "buffer", Scl_CommandBuffer, 1 ); @@ -836,6 +838,108 @@ usage: SeeAlso [] +***********************************************************************/ +int Scl_CommandPower( Abc_Frame_t * pAbc, int argc, char **argv ) +{ + int c; + int fUseWireLoads = 0; + int nTreeCRatio = 0; + int nFrames = 48; + int nPref = 16; + + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "XFPch" ) ) != EOF ) + { + switch ( c ) + { + case 'X': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-X\" should be followed by a positive integer.\n" ); + goto usage; + } + nTreeCRatio = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nTreeCRatio < 0 ) + goto usage; + break; + case 'F': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-F\" should be followed by a positive integer.\n" ); + goto usage; + } + nFrames = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nFrames <= 0 ) + goto usage; + break; + case 'P': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-P\" should be followed by a non-negative integer.\n" ); + goto usage; + } + nPref = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nPref < 0 ) + goto usage; + break; + case 'c': + fUseWireLoads ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + + if ( Abc_FrameReadNtk(pAbc) == NULL ) + { + fprintf( pAbc->Err, "There is no current network.\n" ); + return 1; + } + if ( !Abc_NtkHasMapping(Abc_FrameReadNtk(pAbc)) ) + { + fprintf( pAbc->Err, "The current network is not mapped.\n" ); + return 1; + } + if ( !Abc_SclCheckNtk(Abc_FrameReadNtk(pAbc), 0) ) + { + fprintf( pAbc->Err, "The current network is not in a topo order (run \"topo\").\n" ); + return 1; + } + if ( pAbc->pLibScl == NULL ) + { + fprintf( pAbc->Err, "There is no Liberty library available.\n" ); + return 1; + } + + Abc_SclPowerPerform( (SC_Lib *)pAbc->pLibScl, Abc_FrameReadNtk(pAbc), nTreeCRatio, fUseWireLoads, nFrames, nPref ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: power [-X num] [-F num] [-P num] [-ch]\n" ); + fprintf( pAbc->Err, "\t computes power using Liberty library\n" ); + fprintf( pAbc->Err, "\t-X : min Cout/Cave ratio for tree estimations [default = %d]\n", nTreeCRatio ); + fprintf( pAbc->Err, "\t-F : number of frames to simulate for switching [default = %d]\n", nFrames ); + fprintf( pAbc->Err, "\t-P : number of prefix frames for switching [default = %d]\n", nPref ); + fprintf( pAbc->Err, "\t-c : toggle using wire-loads if specified [default = %s]\n", fUseWireLoads? "yes": "no" ); + fprintf( pAbc->Err, "\t-h : print the help massage\n" ); + return 1; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + ***********************************************************************/ int Scl_CommandStime( Abc_Frame_t * pAbc, int argc, char **argv ) { @@ -2127,4 +2231,3 @@ usage: ABC_NAMESPACE_IMPL_END - diff --git a/src/map/scl/sclLib.h b/src/map/scl/sclLib.h index 1dd86cc3d..fd2f5bb49 100644 --- a/src/map/scl/sclLib.h +++ b/src/map/scl/sclLib.h @@ -40,7 +40,7 @@ ABC_NAMESPACE_HEADER_START /// PARAMETERS /// //////////////////////////////////////////////////////////////////////// -#define ABC_SCL_CUR_VERSION 9 +#define ABC_SCL_CUR_VERSION 10 typedef enum { @@ -232,6 +232,7 @@ struct SC_Lib_ int unit_time; // -- Valid 9..12. Unit is '10^(-val)' seconds (e.g. 9=1ns, 10=100ps, 11=10ps, 12=1ps) float unit_cap_fst; // -- First part is a multiplier, second either 12 or 15 for 'pf' or 'ff'. int unit_cap_snd; + float nom_voltage; // -- nominal voltage, used for external switching power Vec_Ptr_t vWireLoads; // NamedSet Vec_Ptr_t vWireLoadSels; // NamedSet Vec_Ptr_t vTempls; // NamedSet @@ -353,6 +354,7 @@ static inline SC_Lib * Abc_SclLibAlloc() p->unit_time = 9; p->unit_cap_fst = 1; p->unit_cap_snd = 12; + p->nom_voltage = 1; return p; } @@ -496,11 +498,63 @@ static inline float Scl_LibLookup( SC_Surface * p, float slew, float load ) // handle constant table if ( Vec_FltSize(&p->vIndex0) == 1 && Vec_FltSize(&p->vIndex1) == 1 ) { - Vec_Flt_t * vTemp = (Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0); - assert( Vec_PtrSize(&p->vData) == 1 ); + Vec_Flt_t * vTemp; + if ( Vec_PtrSize(&p->vData) != 1 ) + return 0; + vTemp = (Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0); assert( Vec_FltSize(vTemp) == 1 ); + if ( Vec_FltSize(vTemp) != 1 ) + return 0; return Vec_FltEntry(vTemp, 0); } + if ( Vec_FltSize(&p->vIndex0) > 1 && Vec_FltSize(&p->vIndex1) == 1 ) + { + pIndex0 = Vec_FltArray(&p->vIndex0); + for ( s = 1; s < Vec_FltSize(&p->vIndex0)-1; s++ ) + if ( pIndex0[s] > slew ) + break; + s--; + if ( pIndex0[s+1] == pIndex0[s] ) + return 0; + sfrac = (slew - pIndex0[s]) / (pIndex0[s+1] - pIndex0[s]); + if ( Vec_PtrSize(&p->vData) == Vec_FltSize(&p->vIndex0) ) + { + Vec_Flt_t * vDataS = (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s); + Vec_Flt_t * vDataS1 = (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s+1); + if ( Vec_FltSize(vDataS) < 1 || Vec_FltSize(vDataS1) < 1 ) + return 0; + pDataS = Vec_FltArray( vDataS ); + pDataS1 = Vec_FltArray( vDataS1 ); + return pDataS[0] + sfrac * (pDataS1[0] - pDataS[0]); + } + if ( Vec_PtrSize(&p->vData) != 1 ) + return 0; + if ( Vec_FltSize((Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0)) != Vec_FltSize(&p->vIndex0) ) + return 0; + pDataS = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0) ); + return pDataS[s] + sfrac * (pDataS[s+1] - pDataS[s]); + } + if ( Vec_FltSize(&p->vIndex0) == 1 && Vec_FltSize(&p->vIndex1) > 1 ) + { + pIndex1 = Vec_FltArray(&p->vIndex1); + for ( l = 1; l < Vec_FltSize(&p->vIndex1)-1; l++ ) + if ( pIndex1[l] > load ) + break; + l--; + if ( pIndex1[l+1] == pIndex1[l] ) + return 0; + lfrac = (load - pIndex1[l]) / (pIndex1[l+1] - pIndex1[l]); + if ( Vec_PtrSize(&p->vData) != 1 ) + return 0; + if ( Vec_FltSize((Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0)) != Vec_FltSize(&p->vIndex1) ) + return 0; + pDataS = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, 0) ); + return pDataS[l] + lfrac * (pDataS[l+1] - pDataS[l]); + } + if ( Vec_PtrSize(&p->vData) != Vec_FltSize(&p->vIndex0) ) + return 0; + if ( Vec_FltSize(&p->vIndex0) < 2 || Vec_FltSize(&p->vIndex1) < 2 ) + return 0; // Find closest sample points in surface: pIndex0 = Vec_FltArray(&p->vIndex0); @@ -516,9 +570,14 @@ static inline float Scl_LibLookup( SC_Surface * p, float slew, float load ) l--; // Interpolate (or extrapolate) function value from sample points: + if ( pIndex0[s+1] == pIndex0[s] || pIndex1[l+1] == pIndex1[l] ) + return 0; sfrac = (slew - pIndex0[s]) / (pIndex0[s+1] - pIndex0[s]); lfrac = (load - pIndex1[l]) / (pIndex1[l+1] - pIndex1[l]); + if ( Vec_FltSize((Vec_Flt_t *)Vec_PtrEntry(&p->vData, s)) <= l+1 || + Vec_FltSize((Vec_Flt_t *)Vec_PtrEntry(&p->vData, s+1)) <= l+1 ) + return 0; pDataS = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s) ); pDataS1 = Vec_FltArray( (Vec_Flt_t *)Vec_PtrEntry(&p->vData, s+1) ); @@ -666,8 +725,11 @@ static inline SC_Timing * Scl_CellPinOutTime( SC_Cell * pCell, int iOut, int iPi SC_Timings * pRTime; assert( iOut >= 0 && iOut < pCell->n_outputs ); assert( iPin >= 0 && iPin < pCell->n_inputs ); + if ( pCell->n_inputs + iOut >= Vec_PtrSize(&pCell->vPins) ) + return NULL; pPin = SC_CellPin( pCell, pCell->n_inputs + iOut ); - assert( Vec_PtrSize(&pPin->vRTimings) == pCell->n_inputs ); + if ( iPin >= Vec_PtrSize(&pPin->vRTimings) ) + return NULL; pRTime = (SC_Timings *)Vec_PtrEntry( &pPin->vRTimings, iPin ); if ( Vec_PtrSize(&pRTime->vTimings) == 0 ) return NULL; diff --git a/src/map/scl/sclLibScl.c b/src/map/scl/sclLibScl.c index cdd8fb29e..42dd6b78e 100644 --- a/src/map/scl/sclLibScl.c +++ b/src/map/scl/sclLibScl.c @@ -89,6 +89,7 @@ static int Abc_SclReadLibraryGenlib( SC_Lib * p, Mio_Library_t * pLib ) p->unit_time = 12; p->unit_cap_fst = 1.0; p->unit_cap_snd = 15; + p->nom_voltage = 1.0; Mio_LibraryForEachGate( pLib, pGate ) { @@ -251,6 +252,7 @@ static int Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p ) p->unit_time = Vec_StrGetI(vOut, pPos); p->unit_cap_fst = Vec_StrGetF(vOut, pPos); p->unit_cap_snd = Vec_StrGetI(vOut, pPos); + p->nom_voltage = Vec_StrGetF(vOut, pPos); // Read 'wire_load' vector: for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- ) @@ -594,6 +596,7 @@ static void Abc_SclWriteLibrary( Vec_Str_t * vOut, SC_Lib * p, int nExtra, int f Vec_StrPutI( vOut, p->unit_time ); Vec_StrPutF( vOut, p->unit_cap_fst ); Vec_StrPutI( vOut, p->unit_cap_snd ); + Vec_StrPutF( vOut, p->nom_voltage ); // Write 'wire_load' vector: Vec_StrPutI( vOut, Vec_PtrSize(&p->vWireLoads) ); @@ -735,6 +738,7 @@ static void Abc_SclWriteLibraryText( FILE * s, SC_Lib * p ) else if ( p->unit_time == 12 ) fprintf( s, " time_unit : \"1ps\";\n" ); else assert( 0 ); + fprintf( s, " nom_voltage : %f;\n", p->nom_voltage ); fprintf( s, " capacitive_load_unit(%.1f,%s);\n", p->unit_cap_fst, p->unit_cap_snd == 12 ? "pf" : "ff" ); fprintf( s, "\n" ); diff --git a/src/map/scl/sclLibUtil.c b/src/map/scl/sclLibUtil.c index 4115143c3..e132b7341 100644 --- a/src/map/scl/sclLibUtil.c +++ b/src/map/scl/sclLibUtil.c @@ -747,6 +747,14 @@ void Abc_SclLibNormalizeSurface( SC_Surface * p, float Time, float Load ) Vec_FltForEachEntry( vArray, Entry, i ) // delay/slew Vec_FltWriteEntry( vArray, i, Time * Entry ); } +void Abc_SclLibNormalizeSurfaceIndex( SC_Surface * p, float Time, float Load ) +{ + int i; float Entry; + Vec_FltForEachEntry( &p->vIndex0, Entry, i ) // slew + Vec_FltWriteEntry( &p->vIndex0, i, Time * Entry ); + Vec_FltForEachEntry( &p->vIndex1, Entry, i ) // load + Vec_FltWriteEntry( &p->vIndex1, i, Load * Entry ); +} void Abc_SclLibNormalize( SC_Lib * p ) { SC_WireLoad * pWL; @@ -780,6 +788,8 @@ void Abc_SclLibNormalize( SC_Lib * p ) Abc_SclLibNormalizeSurface( &pTiming->pCellFall, Time, Load ); Abc_SclLibNormalizeSurface( &pTiming->pRiseTrans, Time, Load ); Abc_SclLibNormalizeSurface( &pTiming->pFallTrans, Time, Load ); + Abc_SclLibNormalizeSurfaceIndex( &pTiming->pRisePower, Time, Load ); + Abc_SclLibNormalizeSurfaceIndex( &pTiming->pFallPower, Time, Load ); } } } @@ -1134,4 +1144,3 @@ void Abc_SclInstallGenlib( void * pScl, float SlewInit, float Gain, int fUseAll, ABC_NAMESPACE_IMPL_END - diff --git a/src/map/scl/sclLiberty.c b/src/map/scl/sclLiberty.c index 4171aa5fc..98d5e2ab3 100644 --- a/src/map/scl/sclLiberty.c +++ b/src/map/scl/sclLiberty.c @@ -935,6 +935,19 @@ int Scl_LibertyReadTimeUnit( Scl_Tree_t * p ) printf( "Liberty parser cannot read \"time_unit\". Assuming time_unit : \"1ns\".\n" ); return 9; } +float Scl_LibertyReadNomVoltage( Scl_Tree_t * p ) +{ + Scl_Item_t * pItem; + Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "nom_voltage" ) + return atof(Scl_LibertyReadString(p, pItem->Head)); + Scl_ItemForEachChildName( p, Scl_LibertyRoot(p), pItem, "operating_conditions" ) + { + Scl_Item_t * pChild; + Scl_ItemForEachChildName( p, pItem, pChild, "voltage" ) + return atof(Scl_LibertyReadString(p, pChild->Head)); + } + return 1.0; +} void Scl_LibertyReadLoadUnit( Scl_Tree_t * p, Vec_Str_t * vOut ) { Scl_Item_t * pItem; @@ -1606,6 +1619,7 @@ Vec_Str_t * Scl_LibertyReadSclStr( Scl_Tree_t * p, int fVerbose, int fVeryVerbos Vec_StrPutF_( vOut, Scl_LibertyReadDefaultMaxTrans(p) ); Vec_StrPutI_( vOut, Scl_LibertyReadTimeUnit(p) ); Scl_LibertyReadLoadUnit( p, vOut ); + Vec_StrPutF_( vOut, Scl_LibertyReadNomVoltage(p) ); Vec_StrPut_( vOut ); Vec_StrPut_( vOut ); diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index 8d3a2dd5a..a2ba65ee9 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -759,6 +759,92 @@ void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int f Abc_NtkDelete( pNtkNew ); } +/**Function************************************************************* + + Synopsis [Printing out power information for the network.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline float Abc_SclPowerTableLookup( SC_Surface * p, float Slew, float Load ) +{ + Vec_Flt_t * vRow; + int i, nSize0 = Vec_FltSize(&p->vIndex0); + int nSize1 = Vec_FltSize(&p->vIndex1); + if ( nSize0 == 0 || nSize1 == 0 || Vec_PtrSize(&p->vData) != nSize0 ) + return 0; + Vec_PtrForEachEntry( Vec_Flt_t *, &p->vData, vRow, i ) + if ( Vec_FltSize(vRow) != nSize1 ) + return 0; + return Scl_LibLookup( p, Slew, Load ); +} +void Abc_SclPowerPerformInt( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads, int nFrames, int nPref ) +{ + SC_Man * p; + Vec_Flt_t * vSwitching; + Abc_Obj_t * pObj, * pFanin; + double StaticPower = 0, InternalPower = 0, ExternalPower = 0, DynamicPower = 0; + double TotalPower, TotalPowerAbs; + int i, k, nPowerArcs = 0; + p = Abc_SclManStart( pLib, pNtk, fUseWireLoads, 0, 0, nTreeCRatio ); + vSwitching = Abc_SclComputeSwitching( pNtk, nFrames, nPref ); + Abc_NtkForEachNodeNotBarBuf1( pNtk, pObj, i ) + { + SC_Cell * pCell = Abc_SclObjCell( pObj ); + int iOut = Abc_SclObjOutputIndex( pObj, pCell ); + if ( !Abc_SclObjIsSecondTwin(pObj) ) + StaticPower += pCell->leakage; + Abc_ObjForEachFanin( pObj, pFanin, k ) + { + SC_Timing * pTime = Scl_CellPinOutTime( pCell, iOut, k ); + SC_Pair * pLoad = Abc_SclObjLoad( p, pObj ); + SC_Pair * pSlew = Abc_SclObjSlew( p, pFanin ); + float Switch = Vec_FltEntry( vSwitching, Abc_ObjId(pFanin) ); + float RisePower, FallPower; + if ( pTime == NULL ) + { + assert( pCell->n_outputs > 1 ); + continue; + } + RisePower = Abc_SclPowerTableLookup( &pTime->pRisePower, pSlew->rise, pLoad->rise ); + FallPower = Abc_SclPowerTableLookup( &pTime->pFallPower, pSlew->fall, pLoad->fall ); + RisePower = Abc_MaxFloat( 0, RisePower ); + FallPower = Abc_MaxFloat( 0, FallPower ); + if ( RisePower == 0 && FallPower == 0 ) + continue; + InternalPower += Switch * 0.5 * (RisePower + FallPower); + nPowerArcs++; + } + ExternalPower += Vec_FltEntry( vSwitching, Abc_ObjId(pObj) ) * 0.5 * Abc_SclObjLoadAve(p, pObj) * pLib->nom_voltage * pLib->nom_voltage; + } + DynamicPower = InternalPower + ExternalPower; + TotalPower = StaticPower + DynamicPower; + TotalPowerAbs = fabs(StaticPower) + fabs(DynamicPower); + Abc_Print( 1, "WireLoad = \"%s\" ", p->pWLoadUsed ? p->pWLoadUsed->pName : "none" ); + Abc_Print( 1, "Frames = %d Prefix = %d ", nFrames, nPref ); + Abc_Print( 1, "Power = %.6g ", TotalPower ); + Abc_Print( 1, "Static = %.6g (%5.1f %%) ", StaticPower, 100.0 * StaticPower / Abc_MaxDouble(1.0, TotalPowerAbs) ); + Abc_Print( 1, "Dynamic = %.6g (%5.1f %%) ", DynamicPower, 100.0 * DynamicPower / Abc_MaxDouble(1.0, TotalPowerAbs) ); + Abc_Print( 1, "Internal = %.6g ", InternalPower ); + Abc_Print( 1, "External = %.6g ", ExternalPower ); + Abc_Print( 1, "Arcs = %d\n", nPowerArcs ); + Vec_FltFree( vSwitching ); + Abc_SclManFree( p ); +} +void Abc_SclPowerPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads, int nFrames, int nPref ) +{ + Abc_Ntk_t * pNtkNew = pNtk; + if ( pNtk->nBarBufs2 > 0 ) + pNtkNew = Abc_NtkDupDfsNoBarBufs( pNtk ); + Abc_SclPowerPerformInt( pLib, pNtkNew, nTreeCRatio, fUseWireLoads, nFrames, nPref ); + if ( pNtk->nBarBufs2 > 0 ) + Abc_NtkDelete( pNtkNew ); +} + /**Function************************************************************* @@ -972,4 +1058,3 @@ void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose ) ABC_NAMESPACE_IMPL_END - diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h index 6164b4e02..8466469c4 100644 --- a/src/map/scl/sclSize.h +++ b/src/map/scl/sclSize.h @@ -634,6 +634,7 @@ extern int Abc_SclTimeIncUpdate( SC_Man * p ); extern void Abc_SclTimeIncInsert( SC_Man * p, Abc_Obj_t * pObj ); extern void Abc_SclTimeIncUpdateLevel( Abc_Obj_t * pObj ); extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads, int fShowAll, int fPrintPath, int fDumpStats ); +extern void Abc_SclPowerPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int nTreeCRatio, int fUseWireLoads, int nFrames, int nPref ); extern void Abc_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose ); /*=== sclUpsize.c ===============================================================*/ extern int Abc_SclCountNearCriticalNodes( SC_Man * p );