mirror of https://github.com/YosysHQ/abc.git
Changes to command 'upsize'.
This commit is contained in:
parent
508b6f1b13
commit
e0eb270324
|
|
@ -457,6 +457,9 @@ static inline void Abc_ObjSetMvVar( Abc_Obj_t * pObj, void * pV) { Vec_At
|
|||
#define Abc_NtkForEachObjVec( vIds, pNtk, pObj, i ) \
|
||||
for ( i = 0; i < Vec_IntSize(vIds) && (((pObj) = Abc_NtkObj(pNtk, Vec_IntEntry(vIds,i))), 1); i++ ) \
|
||||
if ( (pObj) == NULL ) {} else
|
||||
#define Abc_NtkForEachObjVecStart( vIds, pNtk, pObj, i, Start ) \
|
||||
for ( i = Start; i < Vec_IntSize(vIds) && (((pObj) = Abc_NtkObj(pNtk, Vec_IntEntry(vIds,i))), 1); i++ ) \
|
||||
if ( (pObj) == NULL ) {} else
|
||||
#define Abc_NtkForEachNet( pNtk, pNet, i ) \
|
||||
for ( i = 0; (i < Vec_PtrSize((pNtk)->vObjs)) && (((pNet) = Abc_NtkObj(pNtk, i)), 1); i++ ) \
|
||||
if ( (pNet) == NULL || !Abc_ObjIsNet(pNet) ) {} else
|
||||
|
|
|
|||
|
|
@ -642,34 +642,46 @@ usage:
|
|||
int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
||||
{
|
||||
Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc);
|
||||
int Degree = 2;
|
||||
int nRange = 5;
|
||||
int Window = 5;
|
||||
int Ratio = 5;
|
||||
int nIters = 20;
|
||||
int c, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "NWvh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "WRIvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'N':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-N\" should be followed by a positive integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
Degree = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( Degree < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'W':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-W\" should be followed by a positive integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nRange = atoi(argv[globalUtilOptind]);
|
||||
Window = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nRange < 0 )
|
||||
if ( Window < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'R':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-R\" should be followed by a positive integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
Ratio = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( Ratio < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'I':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-I\" should be followed by a positive integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nIters = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nIters < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'v':
|
||||
|
|
@ -703,14 +715,15 @@ int Scl_CommandUpsize( Abc_Frame_t * pAbc, int argc, char **argv )
|
|||
return 1;
|
||||
}
|
||||
|
||||
Abc_SclUpsizingPerform( pAbc->pLibScl, pNtk, Degree, nRange, fVerbose );
|
||||
Abc_SclUpsizePerform( pAbc->pLibScl, pNtk, Window, Ratio, nIters, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: upsize [-NW num] [-vh]\n" );
|
||||
fprintf( pAbc->Err, "usage: upsize [-WRI num] [-vh]\n" );
|
||||
fprintf( pAbc->Err, "\t selectively increases gate sizes in timing-critical regions\n" );
|
||||
fprintf( pAbc->Err, "\t-N <num> : the max fanout count of gates to upsize [default = %d]\n", Degree );
|
||||
fprintf( pAbc->Err, "\t-W <num> : delay window (in percents) of near-critical COs [default = %d]\n", nRange );
|
||||
fprintf( pAbc->Err, "\t-W <num> : delay window (in percents) of near-critical COs [default = %d]\n", Window );
|
||||
fprintf( pAbc->Err, "\t-R <num> : ratio of critical nodes (in percents) to update [default = %d]\n", Ratio );
|
||||
fprintf( pAbc->Err, "\t-I <num> : the number of upsizing iterations to perform [default = %d]\n", nIters );
|
||||
fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
|
||||
fprintf( pAbc->Err, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ static void Abc_SclReadLibrary( Vec_Str_t * vOut, int * pPos, SC_Lib * p )
|
|||
for ( i = Vec_StrGetI(vOut, pPos); i != 0; i-- )
|
||||
{
|
||||
SC_Cell * pCell = Abc_SclCellAlloc();
|
||||
pCell->Id = Vec_PtrSize(p->vCells);
|
||||
Vec_PtrPush( p->vCells, pCell );
|
||||
|
||||
pCell->pName = Vec_StrGetS(vOut, pPos);
|
||||
|
|
|
|||
|
|
@ -155,6 +155,7 @@ struct SC_Pin_
|
|||
struct SC_Cell_
|
||||
{
|
||||
char * pName;
|
||||
int Id;
|
||||
int seq; // -- set to TRUE by parser if a sequential element
|
||||
int unsupp; // -- set to TRUE by parser if cell contains information we cannot handle
|
||||
float area;
|
||||
|
|
@ -436,7 +437,7 @@ extern void Abc_SclTimePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fUse
|
|||
/*=== sclSize.c =============================================================*/
|
||||
extern void Abc_SclSizingPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * p );
|
||||
/*=== sclUpsize.c =============================================================*/
|
||||
extern void Abc_SclUpsizingPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int Degree, int nRange, int fVerbose );
|
||||
extern void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int Window, int Ratio, int nIters, int fVerbose );
|
||||
/*=== sclUtil.c =============================================================*/
|
||||
extern void Abc_SclHashCells( SC_Lib * p );
|
||||
extern int Abc_SclCellFind( SC_Lib * p, char * pName );
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ static inline float Abc_SclGetMaxDelay( SC_Man * p )
|
|||
fMaxArr = Abc_MaxFloat( fMaxArr, Abc_SclObjTimeMax(p, pObj) );
|
||||
return fMaxArr;
|
||||
}
|
||||
static inline float Abc_SclGetMaxDelayNode( SC_Man * p, Abc_Obj_t * pNode )
|
||||
static inline float Abc_SclGetMaxDelayNodeFanins( SC_Man * p, Abc_Obj_t * pNode )
|
||||
{
|
||||
float fMaxArr = 0;
|
||||
Abc_Obj_t * pObj;
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ void Abc_SclFindCriticalCone_rec( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vVis
|
|||
Abc_NodeSetTravIdCurrent( pObj );
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
// compute timing critical fanin
|
||||
fArrMax = Abc_SclGetMaxDelayNode( p, pObj ) * (100.0 - RangeF) / 100.0;
|
||||
fArrMax = Abc_SclGetMaxDelayNodeFanins( p, pObj ) * (100.0 - RangeF) / 100.0;
|
||||
// traverse all fanins whose arrival times are within a window
|
||||
Abc_ObjForEachFanin( pObj, pNext, i )
|
||||
if ( Abc_SclObjTimeMax(p, pNext) >= fArrMax )
|
||||
|
|
|
|||
|
|
@ -28,10 +28,167 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern Vec_Int_t * Abc_SclFindCriticalCoWindow( SC_Man * p, int Window );
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Collect near-critical COs.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_SclFindCriticalCoWindow( SC_Man * p, int Window )
|
||||
{
|
||||
float fMaxArr = Abc_SclGetMaxDelay( p ) * (100.0 - Window) / 100.0;
|
||||
Vec_Int_t * vPivots;
|
||||
Abc_Obj_t * pObj;
|
||||
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 )
|
||||
{
|
||||
fSlackFan = fSlack - (fArrMax - Abc_SclObjTimeMax(p, pNext));
|
||||
if ( fSlackFan >= 0 )
|
||||
Abc_SclFindCriticalNodeWindow_rec( p, pNext, vPath, fSlackFan );
|
||||
}
|
||||
Vec_IntPush( vPath, Abc_ObjId(pObj) );
|
||||
}
|
||||
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 )
|
||||
Abc_SclFindCriticalNodeWindow_rec( p, Abc_ObjFanin0(pObj), vPath, fSlack - (fMaxArr - Abc_SclObjTimeMax(p, pObj)) );
|
||||
// label critical nodes
|
||||
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 []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Abc_SclFindNodesToUpdate( Abc_Obj_t * pObj )
|
||||
{
|
||||
Vec_Int_t * vNodes;
|
||||
Abc_Obj_t * pNext, * pNext2;
|
||||
int i, k, Start;
|
||||
assert( Abc_ObjIsNode(pObj) );
|
||||
assert( pObj->fMarkA );
|
||||
vNodes = Vec_IntAlloc( 16 );
|
||||
// collect fanins, node, and fanouts
|
||||
Abc_ObjForEachFanin( pObj, pNext, i )
|
||||
if ( Abc_ObjIsNode(pNext) )
|
||||
Vec_IntPush( vNodes, Abc_ObjId(pNext) );
|
||||
Vec_IntPush( vNodes, Abc_ObjId(pObj) );
|
||||
Abc_ObjForEachFanout( pObj, pNext, i )
|
||||
if ( Abc_ObjIsNode(pNext) && pNext->fMarkA )
|
||||
Vec_IntPush( vNodes, Abc_ObjId(pNext) ), pNext->fMarkB = 1;
|
||||
// remember this position
|
||||
Start = Vec_IntSize(vNodes);
|
||||
// label collected nodes
|
||||
Abc_ObjForEachFanout( pObj, pNext, i )
|
||||
if ( Abc_ObjIsNode(pNext) && pNext->fMarkA )
|
||||
Abc_ObjForEachFanout( pNext, pNext2, k )
|
||||
if ( Abc_ObjIsNode(pNext2) && pNext2->fMarkA && !pNext2->fMarkB )
|
||||
Vec_IntPush( vNodes, Abc_ObjId(pNext2) ), pNext2->fMarkB = 1;
|
||||
// clean the fanouts
|
||||
Abc_NtkForEachObjVec( vNodes, pObj->pNtk, pNext, i )
|
||||
pNext->fMarkB = 0;
|
||||
// save position at the last entry
|
||||
Vec_IntPush( vNodes, Start );
|
||||
return vNodes;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Compute gain in changing the gate size.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
float Abc_SclFindGain( SC_Man * p, Vec_Int_t * vCone )
|
||||
{
|
||||
double dGain = 0;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, Start;
|
||||
Start = Vec_IntEntryLast( vCone );
|
||||
vCone->nSize--;
|
||||
|
||||
Abc_SclConeStore( p, vCone );
|
||||
Abc_SclTimeCone( p, vCone );
|
||||
Abc_NtkForEachObjVecStart( vCone, p->pNtk, pObj, i, Start )
|
||||
dGain += Abc_SclObjGain( p, pObj );
|
||||
Abc_SclConeRestore( p, vCone );
|
||||
dGain /= (Vec_IntSize(vCone) - Start);
|
||||
|
||||
vCone->nSize++;
|
||||
return (float)dGain;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Begin by upsizing gates will many fanouts.]
|
||||
|
|
@ -43,27 +200,121 @@ ABC_NAMESPACE_IMPL_START
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_SclManUpsize( SC_Man * p, int Degree )
|
||||
int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio )
|
||||
{
|
||||
SC_Cell * pOld, * pNew;
|
||||
SC_Cell * pCellOld, * pCellNew;
|
||||
Vec_Flt_t * vSavings;
|
||||
Vec_Int_t * vBests;
|
||||
Vec_Int_t * vCone;
|
||||
Vec_Int_t * vUpdates;
|
||||
Abc_Obj_t * pObj;
|
||||
int i, Count = 0;
|
||||
Abc_NtkForEachNode1( p->pNtk, pObj, i )
|
||||
float dGain, dGainBest = 0;
|
||||
int i, k, Entry, gateBest = -1;
|
||||
int nUpsizes = 0;
|
||||
|
||||
vSavings = Vec_FltAlloc( Vec_IntSize(vPathNodes) );
|
||||
vBests = Vec_IntAlloc( Vec_IntSize(vPathNodes) );
|
||||
Abc_NtkForEachObjVec( vPathNodes, p->pNtk, pObj, i )
|
||||
{
|
||||
if ( Abc_ObjFanoutNum(pObj) < Degree )
|
||||
continue;
|
||||
// find new gate
|
||||
pOld = Abc_SclObjCell( p, pObj );
|
||||
pNew = Abc_SclObjResiable( p, pObj, 1 );
|
||||
if ( pNew == NULL )
|
||||
continue;
|
||||
Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), Abc_SclCellFind(p->pLib, pNew->pName) );
|
||||
Count++;
|
||||
dGainBest = 0;
|
||||
pCellOld = Abc_SclObjCell( p, pObj );
|
||||
assert( pCellOld->Id == Vec_IntEntry(p->vGates, Abc_ObjId(pObj)) );
|
||||
// try different gate sizes for this node
|
||||
vCone = Abc_SclFindNodesToUpdate( pObj );
|
||||
SC_RingForEachCell( pCellOld, pCellNew, k )
|
||||
{
|
||||
Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), pCellNew->Id );
|
||||
//printf( "changing %s for %s at node %d ", pCellOld->pName, pCellNew->pName, Abc_ObjId(pObj) );
|
||||
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
|
||||
dGain = Abc_SclFindGain( p, vCone );
|
||||
Abc_SclUpdateLoad( p, pObj, pCellNew, pCellOld );
|
||||
//printf( "gain is %f\n", dGain );
|
||||
if ( dGainBest < dGain )
|
||||
{
|
||||
dGainBest = dGain;
|
||||
gateBest = pCellNew->Id;
|
||||
}
|
||||
}
|
||||
Vec_IntFree( vCone );
|
||||
Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), pCellOld->Id );
|
||||
Vec_FltPush( vSavings, dGainBest );
|
||||
Vec_IntPush( vBests, gateBest );
|
||||
}
|
||||
return Count;
|
||||
assert( Vec_IntSize(vBests) == Vec_IntSize(vPathNodes) );
|
||||
|
||||
// we have computed the gains - find the best ones
|
||||
{
|
||||
Vec_Int_t * vCosts;
|
||||
int * pPerm;
|
||||
float Max = Vec_FltFindMax( vSavings );
|
||||
float Factor = 1.0 * (1<<28) / Max;
|
||||
float This;
|
||||
int i, Limit;
|
||||
// find a good factor
|
||||
vCosts = Vec_IntAlloc( Vec_FltSize(vSavings) );
|
||||
Vec_FltForEachEntry( vSavings, This, i )
|
||||
{
|
||||
Vec_IntPush( vCosts, (int)(This * Factor) );
|
||||
assert( (int)(This * Factor) < (1<<30) );
|
||||
}
|
||||
pPerm = Abc_QuickSortCost( Vec_IntArray(vCosts), Vec_IntSize(vCosts), 1 );
|
||||
assert( Vec_FltEntry(vSavings, pPerm[0]) >= Vec_FltEntry(vSavings, pPerm[Vec_FltSize(vSavings)-1]) );
|
||||
// find those that are good to update
|
||||
Limit = Abc_MinInt( 1, (int)(0.01 * Ratio * Vec_IntSize(vBests)) );
|
||||
vUpdates = Vec_IntAlloc( Limit );
|
||||
for ( i = 0; i < Limit; i++ )
|
||||
if ( Vec_FltEntry(vSavings, pPerm[i]) > 0 )
|
||||
Vec_IntPush( vUpdates, pPerm[i] );
|
||||
}
|
||||
|
||||
// update the network
|
||||
Vec_IntForEachEntry( vUpdates, Entry, i )
|
||||
{
|
||||
pObj = Abc_NtkObj( p->pNtk, Vec_IntEntry(vPathNodes, Entry) );
|
||||
// find new gate
|
||||
pCellOld = Abc_SclObjCell( p, pObj );
|
||||
pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(vBests, Abc_ObjId(pObj)) );
|
||||
assert( pCellNew != NULL );
|
||||
// update gate
|
||||
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
|
||||
p->SumArea += pCellNew->area - pCellOld->area;
|
||||
Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), pCellNew->Id );
|
||||
}
|
||||
|
||||
|
||||
Vec_IntFree( vUpdates );
|
||||
Vec_IntFree( vBests );
|
||||
Vec_FltFree( vSavings );
|
||||
return nUpsizes;
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Print cumulative statistics.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclUpsizePrint( SC_Man * p, int Iter, Vec_Int_t * vPathPos, Vec_Int_t * vPathNodes, int nUpsizes )
|
||||
{
|
||||
printf( "Iter %3d ", Iter );
|
||||
printf( "PathPOs:%5d. ", Vec_IntSize(vPathPos) );
|
||||
printf( "PathNodes:%6d. ", Vec_IntSize(vPathNodes) );
|
||||
printf( "Resized:%5d. ", nUpsizes );
|
||||
printf( "D: " );
|
||||
printf( "%.2f -> %.2f ps ", SC_LibTimePs(p->pLib, p->MaxDelay0), SC_LibTimePs(p->pLib, p->MaxDelay) );
|
||||
printf( "(%+.1f %%). ", 100.0 * (p->MaxDelay - p->MaxDelay0)/ p->MaxDelay0 );
|
||||
printf( "A: " );
|
||||
printf( "%.2f -> %.2f ", p->SumArea0, p->SumArea );
|
||||
printf( "(%+.1f %%). ", 100.0 * (p->SumArea - p->SumArea0)/ p->SumArea0 );
|
||||
Abc_PrintTime( 1, "Time", clock() - p->clkStart );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
@ -75,29 +326,29 @@ int Abc_SclManUpsize( SC_Man * p, int Degree )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Abc_SclUpsizingPerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int Degree, int nRange, int fVerbose )
|
||||
void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, int Window, int Ratio, int nIters, int fVerbose )
|
||||
{
|
||||
SC_Man * p;
|
||||
int nUpsizes;
|
||||
Vec_Int_t * vPathPos; // critical POs
|
||||
Vec_Int_t * vPathNodes; // critical nodes and PIs
|
||||
int i, nUpsizes;
|
||||
|
||||
// prepare the manager; collect init stats
|
||||
p = Abc_SclManStart( pLib, pNtk, 1 );
|
||||
|
||||
// perform upsizing
|
||||
nUpsizes = Abc_SclManUpsize( p, Degree );
|
||||
|
||||
// recompute timing
|
||||
Abc_SclTimeNtkRecompute( p, &p->SumArea, &p->MaxDelay );
|
||||
|
||||
// print cumulative statistics
|
||||
printf( "Resized: %d. ", nUpsizes );
|
||||
printf( "Delay: " );
|
||||
printf( "%.2f -> %.2f ps ", SC_LibTimePs(p->pLib, p->MaxDelay0), SC_LibTimePs(p->pLib, p->MaxDelay) );
|
||||
printf( "(%+.1f %%). ", 100.0 * (p->MaxDelay - p->MaxDelay0)/ p->MaxDelay0 );
|
||||
printf( "Area: " );
|
||||
printf( "%.2f -> %.2f ", p->SumArea0, p->SumArea );
|
||||
printf( "(%+.1f %%). ", 100.0 * (p->SumArea - p->SumArea0)/ p->SumArea0 );
|
||||
Abc_PrintTime( 1, "Time", clock() - p->clkStart );
|
||||
for ( i = 0; i < nIters; i++ )
|
||||
{
|
||||
vPathPos = Abc_SclFindCriticalCoWindow( p, Window );
|
||||
vPathNodes = Abc_SclFindCriticalNodeWindow( p, vPathPos, Window );
|
||||
nUpsizes = Abc_SclFindUpsizes( p, vPathNodes, Ratio );
|
||||
Abc_SclUnmarkCriticalNodeWindow( p, vPathNodes );
|
||||
Abc_SclTimeNtkRecompute( p, &p->SumArea, &p->MaxDelay );
|
||||
Abc_SclUpsizePrint( p, i, vPathPos, vPathNodes, nUpsizes );
|
||||
Vec_IntFree( vPathPos );
|
||||
Vec_IntFree( vPathNodes );
|
||||
}
|
||||
// Abc_NtkCleanMarkAB( pNtk );
|
||||
|
||||
// save the result and quit
|
||||
Abc_SclManSetGates( pLib, pNtk, p->vGates ); // updates gate pointers
|
||||
|
|
|
|||
|
|
@ -617,6 +617,42 @@ static inline int Vec_FltRemove( Vec_Flt_t * p, float Entry )
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find entry.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline float Vec_FltFindMax( Vec_Flt_t * p )
|
||||
{
|
||||
int i;
|
||||
float Best;
|
||||
if ( p->nSize == 0 )
|
||||
return 0;
|
||||
Best = p->pArray[0];
|
||||
for ( i = 1; i < p->nSize; i++ )
|
||||
if ( Best < p->pArray[i] )
|
||||
Best = p->pArray[i];
|
||||
return Best;
|
||||
}
|
||||
static inline float Vec_FltFindMin( Vec_Flt_t * p )
|
||||
{
|
||||
int i;
|
||||
float Best;
|
||||
if ( p->nSize == 0 )
|
||||
return 0;
|
||||
Best = p->pArray[0];
|
||||
for ( i = 1; i < p->nSize; i++ )
|
||||
if ( Best > p->pArray[i] )
|
||||
Best = p->pArray[i];
|
||||
return Best;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Comparison procedure for two floats.]
|
||||
|
|
|
|||
Loading…
Reference in New Issue