2012-09-12 23:39:50 +02:00
/**CFile****************************************************************
FileName [ sclUpsize . c ]
SystemName [ ABC : Logic synthesis and verification system . ]
PackageName [ Standard - cell library representation . ]
Synopsis [ Selective increase of gate sizes . ]
Author [ Alan Mishchenko , Niklas Een ]
Affiliation [ UC Berkeley ]
Date [ Ver . 1.0 . Started - August 24 , 2012. ]
Revision [ $ Id : sclUpsize . c , v 1.0 2012 / 08 / 24 00 : 00 : 00 alanmi Exp $ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "sclInt.h"
# include "sclMan.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
2012-09-18 22:23:58 +02:00
extern Vec_Int_t * Abc_SclFindCriticalCoWindow ( SC_Man * p , int Window ) ;
2012-09-12 23:39:50 +02:00
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
2012-09-19 04:12:54 +02:00
/**Function*************************************************************
Synopsis [ Collect TFO of nodes . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-10-09 06:20:13 +02:00
void Abc_SclFindTFO_rec ( Abc_Obj_t * pObj , Vec_Int_t * vNodes , Vec_Int_t * vCos )
2012-09-19 04:12:54 +02:00
{
Abc_Obj_t * pNext ;
int i ;
if ( Abc_NodeIsTravIdCurrent ( pObj ) )
return ;
Abc_NodeSetTravIdCurrent ( pObj ) ;
2012-10-09 06:20:13 +02:00
if ( Abc_ObjIsCo ( pObj ) )
{
Vec_IntPush ( vCos , Abc_ObjId ( pObj ) ) ;
return ;
}
assert ( Abc_ObjIsNode ( pObj ) ) ;
2012-09-19 04:12:54 +02:00
Abc_ObjForEachFanout ( pObj , pNext , i )
2012-10-09 06:20:13 +02:00
Abc_SclFindTFO_rec ( pNext , vNodes , vCos ) ;
2012-10-09 21:26:58 +02:00
if ( Abc_ObjFaninNum ( pObj ) > 0 )
Vec_IntPush ( vNodes , Abc_ObjId ( pObj ) ) ;
2012-09-19 04:12:54 +02:00
}
Vec_Int_t * Abc_SclFindTFO ( Abc_Ntk_t * p , Vec_Int_t * vPath )
{
2012-10-09 06:20:13 +02:00
Vec_Int_t * vNodes , * vCos ;
2012-09-19 04:12:54 +02:00
Abc_Obj_t * pObj , * pFanin ;
int i , k ;
assert ( Vec_IntSize ( vPath ) > 0 ) ;
2012-10-09 06:20:13 +02:00
vCos = Vec_IntAlloc ( 100 ) ;
vNodes = Vec_IntAlloc ( 100 ) ;
2012-09-19 04:12:54 +02:00
// collect nodes in the TFO
Abc_NtkIncrementTravId ( p ) ;
Abc_NtkForEachObjVec ( vPath , p , pObj , i )
Abc_ObjForEachFanin ( pObj , pFanin , k )
if ( Abc_ObjIsNode ( pFanin ) )
2012-10-09 06:20:13 +02:00
Abc_SclFindTFO_rec ( pFanin , vNodes , vCos ) ;
2012-09-19 04:12:54 +02:00
// reverse order
2012-10-09 06:20:13 +02:00
Vec_IntReverseOrder ( vNodes ) ;
// Vec_IntSort( vNodes, 0 );
//Vec_IntPrint( vNodes );
//Vec_IntPrint( vCos );
Vec_IntAppend ( vNodes , vCos ) ;
Vec_IntFree ( vCos ) ;
return vNodes ;
2012-09-19 04:12:54 +02:00
}
2012-09-12 23:39:50 +02:00
/**Function*************************************************************
2012-09-18 22:23:58 +02:00
Synopsis [ Collect near - critical COs . ]
2012-09-12 23:39:50 +02:00
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-09-18 22:23:58 +02:00
Vec_Int_t * Abc_SclFindCriticalCoWindow ( SC_Man * p , int Window )
2012-09-12 23:39:50 +02:00
{
2012-09-18 22:23:58 +02:00
float fMaxArr = Abc_SclGetMaxDelay ( p ) * ( 100.0 - Window ) / 100.0 ;
Vec_Int_t * vPivots ;
2012-09-12 23:39:50 +02:00
Abc_Obj_t * pObj ;
2012-09-18 22:23:58 +02:00
int i ;
vPivots = Vec_IntAlloc ( 100 ) ;
Abc_NtkForEachCo ( p - > pNtk , pObj , i )
if ( Abc_SclObjTimeMax ( p , pObj ) > = fMaxArr )
Vec_IntPush ( vPivots , Abc_ObjId ( pObj ) ) ;
assert ( Vec_IntSize ( vPivots ) > 0 ) ;
return vPivots ;
}
/**Function*************************************************************
Synopsis [ Collect near - critical internal nodes . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_SclFindCriticalNodeWindow_rec ( SC_Man * p , Abc_Obj_t * pObj , Vec_Int_t * vPath , float fSlack )
{
Abc_Obj_t * pNext ;
float fArrMax , fSlackFan ;
int i ;
if ( Abc_ObjIsCi ( pObj ) )
return ;
if ( Abc_NodeIsTravIdCurrent ( pObj ) )
return ;
Abc_NodeSetTravIdCurrent ( pObj ) ;
assert ( Abc_ObjIsNode ( pObj ) ) ;
// compute the max arrival time of the fanins
fArrMax = Abc_SclGetMaxDelayNodeFanins ( p , pObj ) ;
// traverse all fanins whose arrival times are within a window
Abc_ObjForEachFanin ( pObj , pNext , i )
2012-09-12 23:39:50 +02:00
{
2012-09-18 22:23:58 +02:00
fSlackFan = fSlack - ( fArrMax - Abc_SclObjTimeMax ( p , pNext ) ) ;
if ( fSlackFan > = 0 )
Abc_SclFindCriticalNodeWindow_rec ( p , pNext , vPath , fSlackFan ) ;
2012-09-12 23:39:50 +02:00
}
2012-10-09 21:35:47 +02:00
if ( Abc_ObjFaninNum ( pObj ) > 0 )
Vec_IntPush ( vPath , Abc_ObjId ( pObj ) ) ;
2012-09-18 22:23:58 +02:00
}
Vec_Int_t * Abc_SclFindCriticalNodeWindow ( SC_Man * p , Vec_Int_t * vPathCos , int Window )
{
float fMaxArr = Abc_SclGetMaxDelay ( p ) ;
float fSlack = fMaxArr * Window / 100.0 ;
Vec_Int_t * vPath = Vec_IntAlloc ( 100 ) ;
Abc_Obj_t * pObj ;
int i ;
Abc_NtkIncrementTravId ( p - > pNtk ) ;
Abc_NtkForEachObjVec ( vPathCos , p - > pNtk , pObj , i )
2012-10-09 06:20:13 +02:00
{
float fSlackThis = fSlack - ( fMaxArr - Abc_SclObjTimeMax ( p , pObj ) ) ;
2012-10-09 20:19:58 +02:00
if ( fSlackThis > = 0 )
Abc_SclFindCriticalNodeWindow_rec ( p , Abc_ObjFanin0 ( pObj ) , vPath , fSlackThis ) ;
2012-10-09 06:20:13 +02:00
}
2012-09-18 22:23:58 +02:00
// label critical nodes
2012-09-19 04:12:54 +02:00
Abc_NtkForEachObjVec ( vPathCos , p - > pNtk , pObj , i )
pObj - > fMarkA = 1 ;
2012-09-18 22:23:58 +02:00
Abc_NtkForEachObjVec ( vPath , p - > pNtk , pObj , i )
pObj - > fMarkA = 1 ;
return vPath ;
}
void Abc_SclUnmarkCriticalNodeWindow ( SC_Man * p , Vec_Int_t * vPath )
{
Abc_Obj_t * pObj ;
int i ;
Abc_NtkForEachObjVec ( vPath , p - > pNtk , pObj , i )
pObj - > fMarkA = 0 ;
}
/**Function*************************************************************
Synopsis [ Find the array of nodes to be updated . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-09-19 04:12:54 +02:00
Vec_Int_t * Abc_SclFindNodesToUpdate ( Abc_Obj_t * pPivot , Vec_Int_t * * pvEvals )
2012-09-18 22:23:58 +02:00
{
2012-09-19 04:12:54 +02:00
Abc_Ntk_t * p = Abc_ObjNtk ( pPivot ) ;
Abc_Obj_t * pObj , * pNext , * pNext2 ;
2012-09-18 22:23:58 +02:00
Vec_Int_t * vNodes ;
2012-09-19 04:12:54 +02:00
int i , k ;
assert ( Abc_ObjIsNode ( pPivot ) ) ;
assert ( pPivot - > fMarkA ) ;
2012-09-18 22:23:58 +02:00
// collect fanins, node, and fanouts
2012-09-19 04:12:54 +02:00
vNodes = Vec_IntAlloc ( 16 ) ;
Abc_ObjForEachFanin ( pPivot , pNext , i )
2012-10-09 21:35:47 +02:00
if ( Abc_ObjIsNode ( pNext ) & & Abc_ObjFaninNum ( pNext ) > 0 )
2012-09-18 22:23:58 +02:00
Vec_IntPush ( vNodes , Abc_ObjId ( pNext ) ) ;
2012-09-19 04:12:54 +02:00
Vec_IntPush ( vNodes , Abc_ObjId ( pPivot ) ) ;
Abc_ObjForEachFanout ( pPivot , pNext , i )
2012-09-18 22:23:58 +02:00
if ( Abc_ObjIsNode ( pNext ) & & pNext - > fMarkA )
2012-09-19 04:12:54 +02:00
{
Vec_IntPush ( vNodes , Abc_ObjId ( pNext ) ) ;
2012-09-18 22:23:58 +02:00
Abc_ObjForEachFanout ( pNext , pNext2 , k )
2012-09-19 04:12:54 +02:00
if ( Abc_ObjIsNode ( pNext2 ) & & pNext2 - > fMarkA )
Vec_IntPush ( vNodes , Abc_ObjId ( pNext2 ) ) ;
}
Vec_IntUniqify ( vNodes ) ;
// label nodes
Abc_NtkForEachObjVec ( vNodes , p , pObj , i )
{
assert ( pObj - > fMarkB = = 0 ) ;
pObj - > fMarkB = 1 ;
}
2012-10-09 06:20:13 +02:00
// collect nodes visible from the critical paths
2012-09-19 04:12:54 +02:00
* pvEvals = Vec_IntAlloc ( 10 ) ;
Abc_NtkForEachObjVec ( vNodes , p , pObj , i )
Abc_ObjForEachFanout ( pObj , pNext , k )
if ( pNext - > fMarkA & & ! pNext - > fMarkB )
2012-10-09 10:20:51 +02:00
// if ( !pNext->fMarkB )
2012-09-19 04:12:54 +02:00
{
2012-10-09 06:20:13 +02:00
assert ( pObj - > fMarkB ) ;
2012-09-19 04:12:54 +02:00
Vec_IntPush ( * pvEvals , Abc_ObjId ( pObj ) ) ;
break ;
}
assert ( Vec_IntSize ( * pvEvals ) > 0 ) ;
// label nodes
Abc_NtkForEachObjVec ( vNodes , p , pObj , i )
pObj - > fMarkB = 0 ;
2012-09-18 22:23:58 +02:00
return vNodes ;
2012-09-12 23:39:50 +02:00
}
/**Function*************************************************************
2012-10-09 06:20:13 +02:00
Synopsis [ Computes the set of gates to upsize . ]
2012-09-18 22:23:58 +02:00
Description [ ]
SideEffects [ ]
SeeAlso [ ]
2012-09-12 23:39:50 +02:00
2012-09-18 22:23:58 +02:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-10-09 10:20:51 +02:00
int Abc_SclFindUpsizes ( SC_Man * p , Vec_Int_t * vPathNodes , int Ratio , int Notches , int iIter )
2012-09-18 22:23:58 +02:00
{
SC_Cell * pCellOld , * pCellNew ;
2012-10-09 10:20:51 +02:00
Vec_Int_t * vRecalcs , * vEvals ;
2012-10-09 06:20:13 +02:00
Abc_Obj_t * pObj , * pTemp ;
float dGain , dGainBest ;
2012-10-09 10:20:51 +02:00
int i , k , n , gateBest , Limit , iIterLast ;
2012-09-19 04:12:54 +02:00
2012-10-09 06:20:13 +02:00
// compute savings due to upsizing each node
2012-10-09 10:20:51 +02:00
Vec_QueClear ( p - > vNodeByGain ) ;
2012-09-18 22:23:58 +02:00
Abc_NtkForEachObjVec ( vPathNodes , p - > pNtk , pObj , i )
{
2012-10-09 10:20:51 +02:00
iIterLast = Vec_IntEntry ( p - > vNodeIter , Abc_ObjId ( pObj ) ) ;
if ( iIterLast > = 0 & & iIterLast + 10 > iIter )
continue ;
2012-10-09 06:20:13 +02:00
// compute nodes to recalculate timing and nodes to evaluate afterwards
vRecalcs = Abc_SclFindNodesToUpdate ( pObj , & vEvals ) ;
2012-10-09 10:20:51 +02:00
assert ( Vec_IntSize ( vEvals ) > 0 ) ;
//printf( "%d -> %d\n", Vec_IntSize(vRecalcs), Vec_IntSize(vEvals) );
2012-10-09 06:20:13 +02:00
// save old gate, timing, fanin load
pCellOld = Abc_SclObjCell ( p , pObj ) ;
Abc_SclConeStore ( p , vRecalcs ) ;
Abc_SclLoadStore ( p , pObj ) ;
2012-09-18 22:23:58 +02:00
// try different gate sizes for this node
2012-10-09 06:20:13 +02:00
gateBest = - 1 ;
2012-10-09 10:20:51 +02:00
dGainBest = 0.0 ;
2012-09-18 22:23:58 +02:00
SC_RingForEachCell ( pCellOld , pCellNew , k )
{
2012-09-19 04:12:54 +02:00
if ( pCellNew = = pCellOld )
continue ;
2012-10-09 06:20:13 +02:00
if ( k > Notches )
break ;
// set new cell
2012-09-19 04:12:54 +02:00
Abc_SclObjSetCell ( p , pObj , pCellNew ) ;
2012-09-18 22:23:58 +02:00
Abc_SclUpdateLoad ( p , pObj , pCellOld , pCellNew ) ;
2012-10-09 06:20:13 +02:00
// recompute timing
Abc_SclTimeCone ( p , vRecalcs ) ;
// set old cell
Abc_SclObjSetCell ( p , pObj , pCellOld ) ;
Abc_SclLoadRestore ( p , pObj ) ;
// evaluate gain
dGain = 0.0 ;
Abc_NtkForEachObjVec ( vEvals , p - > pNtk , pTemp , n )
dGain + = Abc_SclObjGain ( p , pTemp ) ;
dGain / = Vec_IntSize ( vEvals ) ;
2012-10-09 10:20:51 +02:00
// save best gain
2012-09-18 22:23:58 +02:00
if ( dGainBest < dGain )
{
dGainBest = dGain ;
gateBest = pCellNew - > Id ;
}
}
2012-10-09 06:20:13 +02:00
// remember savings
2012-10-09 10:20:51 +02:00
if ( gateBest > = 0 )
{
assert ( dGainBest > 0.0 ) ;
Vec_FltWriteEntry ( p - > vNode2Gain , Abc_ObjId ( pObj ) , dGainBest ) ;
Vec_IntWriteEntry ( p - > vNode2Gate , Abc_ObjId ( pObj ) , gateBest ) ;
Vec_QuePush ( p - > vNodeByGain , Abc_ObjId ( pObj ) ) ;
}
2012-10-09 06:20:13 +02:00
// put back old cell and timing
Abc_SclObjSetCell ( p , pObj , pCellOld ) ;
Abc_SclConeRestore ( p , vRecalcs ) ;
// cleanup
Vec_IntFree ( vRecalcs ) ;
Vec_IntFree ( vEvals ) ;
2012-09-18 22:23:58 +02:00
}
2012-10-09 10:20:51 +02:00
if ( Vec_QueSize ( p - > vNodeByGain ) < 3 )
return 0 ;
2012-09-18 22:23:58 +02:00
2012-10-09 10:20:51 +02:00
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) );
for ( i = 0 ; i < Limit ; i + + )
2012-09-18 22:23:58 +02:00
{
2012-09-19 04:12:54 +02:00
// get the object
2012-10-09 10:20:51 +02:00
pObj = Abc_NtkObj ( p - > pNtk , Vec_QuePop ( p - > vNodeByGain ) ) ;
2012-10-09 06:20:13 +02:00
assert ( pObj - > fMarkA ) ;
// find old and new gates
2012-09-18 22:23:58 +02:00
pCellOld = Abc_SclObjCell ( p , pObj ) ;
2012-10-09 10:20:51 +02:00
pCellNew = SC_LibCell ( p - > pLib , Vec_IntEntry ( p - > vNode2Gate , Abc_ObjId ( pObj ) ) ) ;
2012-09-18 22:23:58 +02:00
assert ( pCellNew ! = NULL ) ;
2012-10-09 10:20:51 +02:00
// printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName );
// printf( "gain is %f\n", Vec_FltEntry(p->vNode2Gain, Abc_ObjId(pObj)) );
2012-09-18 22:23:58 +02:00
// update gate
Abc_SclUpdateLoad ( p , pObj , pCellOld , pCellNew ) ;
p - > SumArea + = pCellNew - > area - pCellOld - > area ;
2012-09-19 04:12:54 +02:00
Abc_SclObjSetCell ( p , pObj , pCellNew ) ;
2012-10-09 06:20:13 +02:00
// record the update
Vec_IntPush ( p - > vUpdates , Abc_ObjId ( pObj ) ) ;
Vec_IntPush ( p - > vUpdates , pCellNew - > Id ) ;
2012-10-09 10:20:51 +02:00
// remember when this node was upsized
Vec_IntWriteEntry ( p - > vNodeIter , Abc_ObjId ( pObj ) , iIter ) ;
2012-09-18 22:23:58 +02:00
}
2012-10-09 10:20:51 +02:00
return Limit ;
2012-09-18 22:23:58 +02:00
}
2012-10-09 06:20:13 +02:00
void Abc_SclApplyUpdateToBest ( Vec_Int_t * vGates , Vec_Int_t * vGatesBest , Vec_Int_t * vUpdate )
{
int i , ObjId , GateId , GateId2 ;
Vec_IntForEachEntryDouble ( vUpdate , ObjId , GateId , i )
Vec_IntWriteEntry ( vGatesBest , ObjId , GateId ) ;
Vec_IntClear ( vUpdate ) ;
Vec_IntForEachEntryTwo ( vGates , vGatesBest , GateId , GateId2 , i )
assert ( GateId = = GateId2 ) ;
}
2012-09-18 22:23:58 +02:00
2012-10-09 06:20:13 +02:00
/**Function*************************************************************
Synopsis [ ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void Abc_SclUpsizePrintDiffs ( SC_Man * p , SC_Lib * pLib , Abc_Ntk_t * pNtk )
{
float fDiff = ( float ) 0.001 ;
int k ;
Abc_Obj_t * pObj ;
SC_Pair * pTimes = ABC_ALLOC ( SC_Pair , p - > nObjs ) ;
SC_Pair * pSlews = ABC_ALLOC ( SC_Pair , p - > nObjs ) ;
SC_Pair * pLoads = ABC_ALLOC ( SC_Pair , p - > nObjs ) ;
memcpy ( pTimes , p - > pTimes , sizeof ( SC_Pair ) * p - > nObjs ) ;
memcpy ( pSlews , p - > pSlews , sizeof ( SC_Pair ) * p - > nObjs ) ;
memcpy ( pLoads , p - > pLoads , sizeof ( SC_Pair ) * p - > nObjs ) ;
Abc_SclTimeNtkRecompute ( p , NULL , NULL , 0 ) ;
Abc_NtkForEachNode ( pNtk , pObj , k )
{
if ( Abc_AbsFloat ( p - > pLoads [ k ] . rise - pLoads [ k ] . rise ) > fDiff )
printf ( " %6d : load rise differs %12.6f %f %f \n " , k , SC_LibCapFf ( pLib , p - > pLoads [ k ] . rise ) - SC_LibCapFf ( pLib , pLoads [ k ] . rise ) , SC_LibCapFf ( pLib , p - > pLoads [ k ] . rise ) , SC_LibCapFf ( pLib , pLoads [ k ] . rise ) ) ;
if ( Abc_AbsFloat ( p - > pLoads [ k ] . fall - pLoads [ k ] . fall ) > fDiff )
printf ( " %6d : load fall differs %12.6f %f %f \n " , k , SC_LibCapFf ( pLib , p - > pLoads [ k ] . fall ) - SC_LibCapFf ( pLib , pLoads [ k ] . fall ) , SC_LibCapFf ( pLib , p - > pLoads [ k ] . fall ) , SC_LibCapFf ( pLib , pLoads [ k ] . fall ) ) ;
if ( Abc_AbsFloat ( p - > pSlews [ k ] . rise - pSlews [ k ] . rise ) > fDiff )
printf ( " %6d : slew rise differs %12.6f %f %f \n " , k , SC_LibTimePs ( pLib , p - > pSlews [ k ] . rise ) - SC_LibTimePs ( pLib , pSlews [ k ] . rise ) , SC_LibTimePs ( pLib , p - > pSlews [ k ] . rise ) , SC_LibTimePs ( pLib , pSlews [ k ] . rise ) ) ;
if ( Abc_AbsFloat ( p - > pSlews [ k ] . fall - pSlews [ k ] . fall ) > fDiff )
printf ( " %6d : slew fall differs %12.6f %f %f \n " , k , SC_LibTimePs ( pLib , p - > pSlews [ k ] . fall ) - SC_LibTimePs ( pLib , pSlews [ k ] . fall ) , SC_LibTimePs ( pLib , p - > pSlews [ k ] . fall ) , SC_LibTimePs ( pLib , pSlews [ k ] . fall ) ) ;
if ( Abc_AbsFloat ( p - > pTimes [ k ] . rise - pTimes [ k ] . rise ) > fDiff )
printf ( " %6d : time rise differs %12.6f %f %f \n " , k , SC_LibTimePs ( pLib , p - > pTimes [ k ] . rise ) - SC_LibTimePs ( pLib , pTimes [ k ] . rise ) , SC_LibTimePs ( pLib , p - > pTimes [ k ] . rise ) , SC_LibTimePs ( pLib , pTimes [ k ] . rise ) ) ;
if ( Abc_AbsFloat ( p - > pTimes [ k ] . fall - pTimes [ k ] . fall ) > fDiff )
printf ( " %6d : time fall differs %12.6f %f %f \n " , k , SC_LibTimePs ( pLib , p - > pTimes [ k ] . fall ) - SC_LibTimePs ( pLib , pTimes [ k ] . fall ) , SC_LibTimePs ( pLib , p - > pTimes [ k ] . fall ) , SC_LibTimePs ( pLib , pTimes [ k ] . fall ) ) ;
}
/*
if ( memcmp ( pTimes , p - > pTimes , sizeof ( SC_Pair ) * p - > nObjs ) )
printf ( " Times differ! \n " ) ;
if ( memcmp ( pSlews , p - > pSlews , sizeof ( SC_Pair ) * p - > nObjs ) )
printf ( " Slews differ! \n " ) ;
if ( memcmp ( pLoads , p - > pLoads , sizeof ( SC_Pair ) * p - > nObjs ) )
printf ( " Loads differ! \n " ) ;
*/
ABC_FREE ( pTimes ) ;
ABC_FREE ( pSlews ) ;
ABC_FREE ( pLoads ) ;
}
2012-09-18 22:23:58 +02:00
/**Function*************************************************************
Synopsis [ Print cumulative statistics . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
2012-09-12 23:39:50 +02:00
2012-09-18 22:23:58 +02:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-10-09 10:20:51 +02:00
void Abc_SclUpsizePrint ( SC_Man * p , int Iter , int win , int nPathPos , int nPathNodes , int nUpsizes , int nTFOs , int fVerbose )
2012-09-18 22:23:58 +02:00
{
2012-10-09 06:20:13 +02:00
printf ( " %4d " , Iter ) ;
2012-10-09 10:20:51 +02:00
printf ( " Win:%3d. " , win ) ;
2012-10-09 06:20:13 +02:00
printf ( " PO:%5d. " , nPathPos ) ;
printf ( " Path:%6d. " , nPathNodes ) ;
printf ( " Gate:%5d. " , nUpsizes ) ;
printf ( " TFO:%6d. " , nTFOs ) ;
printf ( " B: " ) ;
printf ( " %.2f ps " , SC_LibTimePs ( p - > pLib , p - > BestDelay ) ) ;
printf ( " (%+5.1f %%) " , 100.0 * ( p - > BestDelay - p - > MaxDelay0 ) / p - > MaxDelay0 ) ;
2012-09-18 22:23:58 +02:00
printf ( " D: " ) ;
2012-10-09 06:20:13 +02:00
printf ( " %.2f ps " , SC_LibTimePs ( p - > pLib , p - > MaxDelay ) ) ;
printf ( " (%+5.1f %%) " , 100.0 * ( p - > MaxDelay - p - > MaxDelay0 ) / p - > MaxDelay0 ) ;
2012-09-18 22:23:58 +02:00
printf ( " A: " ) ;
2012-10-09 06:20:13 +02:00
printf ( " %.2f " , p - > SumArea ) ;
2012-10-09 23:27:49 +02:00
printf ( " (%+5.1f %%) " , 100.0 * ( p - > SumArea - p - > SumArea0 ) / p - > SumArea0 ) ;
printf ( " %8.2f " , 1.0 * ( clock ( ) - p - > timeTotal ) / ( CLOCKS_PER_SEC ) ) ;
2012-10-09 20:00:18 +02:00
printf ( " " ) ;
printf ( " %c " , fVerbose ? ' \n ' : ' \r ' ) ;
2012-09-18 22:23:58 +02:00
}
/**Function*************************************************************
Synopsis [ ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2012-10-09 23:27:49 +02:00
void Abc_SclUpsizePerform ( SC_Lib * pLib , Abc_Ntk_t * pNtk , int nIters , int nIterNoChange , int Window , int Ratio , int Notches , int TimeOut , int fDumpStats , int fVerbose , int fVeryVerbose )
2012-09-18 22:23:58 +02:00
{
SC_Man * p ;
2012-10-09 20:21:36 +02:00
Vec_Int_t * vPathPos = NULL ; // critical POs
Vec_Int_t * vPathNodes = NULL ; // critical nodes and PIs
2012-09-19 04:12:54 +02:00
Vec_Int_t * vTFO ;
2012-10-09 23:27:49 +02:00
int i , win , nUpsizes = - 1 , nFramesNoChange = 0 ;
2012-10-09 06:20:13 +02:00
int nAllPos , nAllNodes , nAllTfos , nAllUpsizes ;
clock_t clk ;
if ( fVerbose )
{
printf ( " Sizing parameters: " ) ;
printf ( " Iters =%4d. " , nIters ) ;
printf ( " Time window =%3d %%. " , Window ) ;
printf ( " Update ratio =%3d %%. " , Ratio ) ;
printf ( " Max upsize steps =%2d. " , Notches ) ;
printf ( " Timeout =%3d sec " , TimeOut ) ;
printf ( " \n " ) ;
}
2012-09-18 22:23:58 +02:00
// prepare the manager; collect init stats
p = Abc_SclManStart ( pLib , pNtk , 1 ) ;
2012-10-09 06:20:13 +02:00
p - > timeTotal = clock ( ) ;
assert ( p - > vGatesBest = = NULL ) ;
p - > vGatesBest = Vec_IntDup ( p - > vGates ) ;
p - > BestDelay = p - > MaxDelay0 ;
2012-09-18 22:23:58 +02:00
// perform upsizing
2012-10-09 06:20:13 +02:00
nAllPos = nAllNodes = nAllTfos = nAllUpsizes = 0 ;
2012-10-09 10:20:51 +02:00
for ( i = 0 ; i < nIters ; i + + )
2012-09-18 22:23:58 +02:00
{
2012-10-09 10:20:51 +02:00
for ( win = Window ; win < = 100 ; win * = 2 )
{
// detect critical path
clk = clock ( ) ;
vPathPos = Abc_SclFindCriticalCoWindow ( p , win ) ;
vPathNodes = Abc_SclFindCriticalNodeWindow ( p , vPathPos , win ) ;
p - > timeCone + = clock ( ) - clk ;
// selectively upsize the nodes
clk = clock ( ) ;
nUpsizes = Abc_SclFindUpsizes ( p , vPathNodes , Ratio , Notches , i ) ;
p - > timeSize + = clock ( ) - clk ;
// unmark critical path
clk = clock ( ) ;
Abc_SclUnmarkCriticalNodeWindow ( p , vPathNodes ) ;
Abc_SclUnmarkCriticalNodeWindow ( p , vPathPos ) ;
p - > timeCone + = clock ( ) - clk ;
if ( nUpsizes > 0 )
break ;
Vec_IntFree ( vPathPos ) ;
Vec_IntFree ( vPathNodes ) ;
}
if ( nUpsizes = = 0 )
break ;
2012-09-19 04:12:54 +02:00
2012-10-09 06:20:13 +02:00
// update timing information
clk = clock ( ) ;
2012-10-10 00:25:34 +02:00
// vTFO = Abc_SclFindTFO( p->pNtk, vPathNodes );
// Abc_SclTimeCone( p, vTFO );
vTFO = Vec_IntAlloc ( 0 ) ;
Abc_SclTimeNtkRecompute ( p , NULL , NULL , 0 ) ;
2012-10-09 06:20:13 +02:00
p - > timeTime + = clock ( ) - clk ;
// Abc_SclUpsizePrintDiffs( p, pLib, pNtk );
// save the best network
2012-09-19 04:12:54 +02:00
p - > MaxDelay = Abc_SclGetMaxDelay ( p ) ;
2012-10-09 06:20:13 +02:00
if ( p - > BestDelay > p - > MaxDelay )
{
p - > BestDelay = p - > MaxDelay ;
Abc_SclApplyUpdateToBest ( p - > vGates , p - > vGatesBest , p - > vUpdates ) ;
2012-10-09 23:27:49 +02:00
nFramesNoChange = 0 ;
2012-10-09 06:20:13 +02:00
}
2012-10-09 23:27:49 +02:00
else
nFramesNoChange + + ;
if ( nFramesNoChange > nIterNoChange )
break ;
2012-09-19 04:12:54 +02:00
2012-10-09 06:20:13 +02:00
// report and cleanup
2012-10-09 10:20:51 +02:00
Abc_SclUpsizePrint ( p , i , win , Vec_IntSize ( vPathPos ) , Vec_IntSize ( vPathNodes ) , nUpsizes , Vec_IntSize ( vTFO ) , fVeryVerbose ) ; //|| (i == nIters-1) );
2012-10-09 06:20:13 +02:00
nAllPos + = Vec_IntSize ( vPathPos ) ;
nAllNodes + = Vec_IntSize ( vPathNodes ) ;
nAllTfos + = Vec_IntSize ( vTFO ) ;
nAllUpsizes + = nUpsizes ;
2012-09-18 22:23:58 +02:00
Vec_IntFree ( vPathPos ) ;
Vec_IntFree ( vPathNodes ) ;
2012-09-19 04:12:54 +02:00
Vec_IntFree ( vTFO ) ;
2012-09-18 22:23:58 +02:00
}
2012-10-09 06:20:13 +02:00
// update for best gates and recompute timing
ABC_SWAP ( Vec_Int_t * , p - > vGatesBest , p - > vGates ) ;
2012-10-09 20:00:18 +02:00
Abc_SclTimeNtkRecompute ( p , & p - > SumArea , & p - > MaxDelay , 0 ) ;
2012-10-09 21:35:47 +02:00
if ( fVerbose )
Abc_SclUpsizePrint ( p , i , Window , nAllPos / i , nAllNodes / i , nAllUpsizes / i , nAllTfos / i , 1 ) ;
// report runtime
2012-10-09 20:00:18 +02:00
p - > timeTotal = clock ( ) - p - > timeTotal ;
2012-10-09 06:20:13 +02:00
if ( fVerbose )
{
p - > timeOther = p - > timeTotal - p - > timeCone - p - > timeSize - p - > timeTime ;
ABC_PRTP ( " Runtime: Critical path " , p - > timeCone , p - > timeTotal ) ;
ABC_PRTP ( " Runtime: Sizing eval " , p - > timeSize , p - > timeTotal ) ;
ABC_PRTP ( " Runtime: Timing update " , p - > timeTime , p - > timeTotal ) ;
ABC_PRTP ( " Runtime: Other " , p - > timeOther , p - > timeTotal ) ;
ABC_PRTP ( " Runtime: TOTAL " , p - > timeTotal , p - > timeTotal ) ;
}
2012-10-09 20:19:58 +02:00
if ( fDumpStats )
Abc_SclDumpStats ( p , " stats2.txt " , p - > timeTotal ) ;
2012-09-12 23:39:50 +02:00
// save the result and quit
Abc_SclManSetGates ( pLib , pNtk , p - > vGates ) ; // updates gate pointers
Abc_SclManFree ( p ) ;
2012-10-09 06:20:13 +02:00
// Abc_NtkCleanMarkAB( pNtk );
2012-09-12 23:39:50 +02:00
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END