Commit 655dc4e7 by Alan Mishchenko

Improvements to buffering and sizing.

parent 8576e4b4
...@@ -53,13 +53,13 @@ struct SC_Man_ ...@@ -53,13 +53,13 @@ struct SC_Man_
Vec_Int_t * vUpdates2; // sizing updates in this round Vec_Int_t * vUpdates2; // sizing updates in this round
// timing information // timing information
SC_Pair * pLoads; // loads for each gate SC_Pair * pLoads; // loads for each gate
SC_Pair * pLoads2; // loads for each gate
SC_Pair * pLoads3; // loads for each gate
SC_Pair * pDepts; // departures for each gate SC_Pair * pDepts; // departures for each gate
SC_Pair * pTimes; // arrivals for each gate SC_Pair * pTimes; // arrivals for each gate
SC_Pair * pSlews; // slews for each gate SC_Pair * pSlews; // slews for each gate
SC_Pair * pTimes2; // arrivals for each gate SC_Pair * pTimes2; // arrivals for each gate
SC_Pair * pSlews2; // slews for each gate SC_Pair * pSlews2; // slews for each gate
Vec_Flt_t * vLoads2; // backup storage for loads
Vec_Flt_t * vLoads3; // backup storage for loads
float * pSlack; // slacks for each gatt float * pSlack; // slacks for each gatt
float * pInDrive; // maximum input drive strength float * pInDrive; // maximum input drive strength
Vec_Int_t * vBestFans; // best fanouts Vec_Int_t * vBestFans; // best fanouts
...@@ -103,8 +103,6 @@ static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj ) ...@@ -103,8 +103,6 @@ static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj )
static inline void Abc_SclObjSetCell( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell ) { Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), pCell->Id ); } static inline void Abc_SclObjSetCell( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell ) { Vec_IntWriteEntry( p->vGates, Abc_ObjId(pObj), pCell->Id ); }
static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + Abc_ObjId(pObj); } static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + Abc_ObjId(pObj); }
static inline SC_Pair * Abc_SclObjLoad2( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads2 + Abc_ObjId(pObj); }
static inline SC_Pair * Abc_SclObjLoad3( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads3 + Abc_ObjId(pObj); }
static inline SC_Pair * Abc_SclObjDept( SC_Man * p, Abc_Obj_t * pObj ) { return p->pDepts + Abc_ObjId(pObj); } static inline SC_Pair * Abc_SclObjDept( SC_Man * p, Abc_Obj_t * pObj ) { return p->pDepts + Abc_ObjId(pObj); }
static inline SC_Pair * Abc_SclObjTime( SC_Man * p, Abc_Obj_t * pObj ) { return p->pTimes + Abc_ObjId(pObj); } static inline SC_Pair * Abc_SclObjTime( SC_Man * p, Abc_Obj_t * pObj ) { return p->pTimes + Abc_ObjId(pObj); }
static inline SC_Pair * Abc_SclObjSlew( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlews + Abc_ObjId(pObj); } static inline SC_Pair * Abc_SclObjSlew( SC_Man * p, Abc_Obj_t * pObj ) { return p->pSlews + Abc_ObjId(pObj); }
...@@ -153,8 +151,6 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk ) ...@@ -153,8 +151,6 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
p->pNtk = pNtk; p->pNtk = pNtk;
p->nObjs = Abc_NtkObjNumMax(pNtk); p->nObjs = Abc_NtkObjNumMax(pNtk);
p->pLoads = ABC_CALLOC( SC_Pair, p->nObjs ); p->pLoads = ABC_CALLOC( SC_Pair, p->nObjs );
p->pLoads2 = ABC_CALLOC( SC_Pair, p->nObjs );
p->pLoads3 = ABC_CALLOC( SC_Pair, p->nObjs );
p->pDepts = ABC_CALLOC( SC_Pair, p->nObjs ); p->pDepts = ABC_CALLOC( SC_Pair, p->nObjs );
p->pTimes = ABC_CALLOC( SC_Pair, p->nObjs ); p->pTimes = ABC_CALLOC( SC_Pair, p->nObjs );
p->pSlews = ABC_CALLOC( SC_Pair, p->nObjs ); p->pSlews = ABC_CALLOC( SC_Pair, p->nObjs );
...@@ -169,6 +165,8 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk ) ...@@ -169,6 +165,8 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk )
Vec_QuePush( p->vQue, i ); Vec_QuePush( p->vQue, i );
p->vUpdates = Vec_IntAlloc( 1000 ); p->vUpdates = Vec_IntAlloc( 1000 );
p->vUpdates2 = Vec_IntAlloc( 1000 ); p->vUpdates2 = Vec_IntAlloc( 1000 );
p->vLoads2 = Vec_FltAlloc( 1000 );
p->vLoads3 = Vec_FltAlloc( 1000 );
// intermediate data // intermediate data
p->vNode2Gain = Vec_FltStart( p->nObjs ); p->vNode2Gain = Vec_FltStart( p->nObjs );
p->vNode2Gate = Vec_IntStart( p->nObjs ); p->vNode2Gate = Vec_IntStart( p->nObjs );
...@@ -184,6 +182,8 @@ static inline void Abc_SclManFree( SC_Man * p ) ...@@ -184,6 +182,8 @@ static inline void Abc_SclManFree( SC_Man * p )
Vec_FltFreeP( &p->vNode2Gain ); Vec_FltFreeP( &p->vNode2Gain );
Vec_IntFreeP( &p->vNode2Gate ); Vec_IntFreeP( &p->vNode2Gate );
// intermediate data // intermediate data
Vec_FltFreeP( &p->vLoads2 );
Vec_FltFreeP( &p->vLoads3 );
Vec_IntFreeP( &p->vUpdates ); Vec_IntFreeP( &p->vUpdates );
Vec_IntFreeP( &p->vUpdates2 ); Vec_IntFreeP( &p->vUpdates2 );
Vec_IntFreeP( &p->vGatesBest ); Vec_IntFreeP( &p->vGatesBest );
...@@ -194,8 +194,6 @@ static inline void Abc_SclManFree( SC_Man * p ) ...@@ -194,8 +194,6 @@ static inline void Abc_SclManFree( SC_Man * p )
Vec_IntFreeP( &p->vGates ); Vec_IntFreeP( &p->vGates );
Vec_IntFreeP( &p->vBestFans ); Vec_IntFreeP( &p->vBestFans );
ABC_FREE( p->pLoads ); ABC_FREE( p->pLoads );
ABC_FREE( p->pLoads2 );
ABC_FREE( p->pLoads3 );
ABC_FREE( p->pDepts ); ABC_FREE( p->pDepts );
ABC_FREE( p->pTimes ); ABC_FREE( p->pTimes );
ABC_FREE( p->pSlews ); ABC_FREE( p->pSlews );
...@@ -288,32 +286,50 @@ static inline void Abc_SclLoadStore( SC_Man * p, Abc_Obj_t * pObj ) ...@@ -288,32 +286,50 @@ static inline void Abc_SclLoadStore( SC_Man * p, Abc_Obj_t * pObj )
{ {
Abc_Obj_t * pFanin; Abc_Obj_t * pFanin;
int i; int i;
Vec_FltClear( p->vLoads2 );
Abc_ObjForEachFanin( pObj, pFanin, i ) Abc_ObjForEachFanin( pObj, pFanin, i )
*Abc_SclObjLoad2(p, pFanin) = *Abc_SclObjLoad(p, pFanin); {
Vec_FltPush( p->vLoads2, Abc_SclObjLoad(p, pFanin)->rise );
Vec_FltPush( p->vLoads2, Abc_SclObjLoad(p, pFanin)->fall );
}
} }
static inline void Abc_SclLoadRestore( SC_Man * p, Abc_Obj_t * pObj ) static inline void Abc_SclLoadRestore( SC_Man * p, Abc_Obj_t * pObj )
{ {
Abc_Obj_t * pFanin; Abc_Obj_t * pFanin;
int i; int i;
assert( Vec_FltSize(p->vLoads2) == 2 * Abc_ObjFaninNum(pObj) );
Abc_ObjForEachFanin( pObj, pFanin, i ) Abc_ObjForEachFanin( pObj, pFanin, i )
*Abc_SclObjLoad(p, pFanin) = *Abc_SclObjLoad2(p, pFanin); {
Abc_SclObjLoad(p, pFanin)->rise = Vec_FltEntry(p->vLoads2, 2*i);
Abc_SclObjLoad(p, pFanin)->fall = Vec_FltEntry(p->vLoads2, 2*i+1);
}
} }
static inline void Abc_SclLoadStore3( SC_Man * p, Abc_Obj_t * pObj ) static inline void Abc_SclLoadStore3( SC_Man * p, Abc_Obj_t * pObj )
{ {
Abc_Obj_t * pFanin; Abc_Obj_t * pFanin;
int i; int i;
*Abc_SclObjLoad3(p, pObj) = *Abc_SclObjLoad(p, pObj); Vec_FltClear( p->vLoads3 );
Abc_ObjForEachFanin( pObj, pFanin, i ) Abc_ObjForEachFanin( pObj, pFanin, i )
*Abc_SclObjLoad3(p, pFanin) = *Abc_SclObjLoad(p, pFanin); {
Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pFanin)->rise );
Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pFanin)->fall );
}
Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pObj)->rise );
Vec_FltPush( p->vLoads3, Abc_SclObjLoad(p, pObj)->fall );
} }
static inline void Abc_SclLoadRestore3( SC_Man * p, Abc_Obj_t * pObj ) static inline void Abc_SclLoadRestore3( SC_Man * p, Abc_Obj_t * pObj )
{ {
Abc_Obj_t * pFanin; Abc_Obj_t * pFanin;
int i; int i;
*Abc_SclObjLoad(p, pObj) = *Abc_SclObjLoad3(p, pObj); assert( Vec_FltSize(p->vLoads3) == 2 * Abc_ObjFaninNum(pObj) + 2 );
Abc_ObjForEachFanin( pObj, pFanin, i ) Abc_ObjForEachFanin( pObj, pFanin, i )
*Abc_SclObjLoad(p, pFanin) = *Abc_SclObjLoad3(p, pFanin); {
Abc_SclObjLoad(p, pFanin)->rise = Vec_FltEntry(p->vLoads3, 2*i);
Abc_SclObjLoad(p, pFanin)->fall = Vec_FltEntry(p->vLoads3, 2*i+1);
}
Abc_SclObjLoad(p, pObj)->rise = Vec_FltEntry(p->vLoads3, 2*i);
Abc_SclObjLoad(p, pObj)->fall = Vec_FltEntry(p->vLoads3, 2*i+1);
} }
/**Function************************************************************* /**Function*************************************************************
......
...@@ -193,7 +193,7 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath ) ...@@ -193,7 +193,7 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int_t ** pvEvals ) void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int_t ** pvEvals, Abc_Obj_t * pExtra )
{ {
Abc_Ntk_t * p = Abc_ObjNtk(pPivot); Abc_Ntk_t * p = Abc_ObjNtk(pPivot);
Abc_Obj_t * pObj, * pNext, * pNext2; Abc_Obj_t * pObj, * pNext, * pNext2;
...@@ -208,6 +208,8 @@ void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int ...@@ -208,6 +208,8 @@ void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int
if ( Abc_ObjIsNode(pNext) && Abc_ObjFaninNum(pNext) > 0 ) if ( Abc_ObjIsNode(pNext) && Abc_ObjFaninNum(pNext) > 0 )
Vec_IntPush( vNodes, Abc_ObjId(pNext) ); Vec_IntPush( vNodes, Abc_ObjId(pNext) );
Vec_IntPush( vNodes, Abc_ObjId(pPivot) ); Vec_IntPush( vNodes, Abc_ObjId(pPivot) );
if ( pExtra )
Vec_IntPush( vNodes, Abc_ObjId(pExtra) );
Abc_ObjForEachFanout( pPivot, pNext, i ) Abc_ObjForEachFanout( pPivot, pNext, i )
if ( Abc_ObjIsNode(pNext) && pNext->fMarkA ) if ( Abc_ObjIsNode(pNext) && pNext->fMarkA )
{ {
...@@ -243,7 +245,7 @@ void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int ...@@ -243,7 +245,7 @@ void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int
/**Function************************************************************* /**Function*************************************************************
Synopsis [Computes the set of gates to upsize.] Synopsis []
Description [] Description []
...@@ -252,63 +254,19 @@ void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int ...@@ -252,63 +254,19 @@ void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notches, int iIter, int DelayGap, int fVeryVerbose ) int Abc_SclFindBestCell( SC_Man * p, Abc_Obj_t * pObj, Vec_Int_t * vRecalcs, Vec_Int_t * vEvals, int Notches, int DelayGap, float * pGainBest )
{ {
SC_Cell * pCellOld, * pCellNew; SC_Cell * pCellOld, * pCellNew;
Vec_Ptr_t * vFanouts; Abc_Obj_t * pTemp;
Vec_Int_t * vRecalcs, * vEvals; float dGain, dGainBest, gGainCur;
Abc_Obj_t * pObj, * pTemp, * pBuffer, * pFanout; int k, n, gateBest;
float dGain, dGainBest, dGainBest2;
int i, j, k, n, gateBest, gateBest2, fanBest, Counter = 0;
// compute savings due to bypassing buffers
vFanouts = Vec_PtrAlloc( 100 );
vRecalcs = Vec_IntAlloc( 100 );
vEvals = Vec_IntAlloc( 100 );
Vec_QueClear( p->vNodeByGain );
Abc_NtkForEachObjVec( vPathNodes, p->pNtk, pBuffer, i )
{
assert( pBuffer->fMarkC == 0 );
if ( Abc_ObjFaninNum(pBuffer) != 1 )
continue;
pObj = Abc_ObjFanin0(pBuffer);
if ( !Abc_ObjIsNode(pObj) )
continue;
// here we have pBuffer and its fanin pObj, which is a logic node
// compute nodes to recalculate timing and nodes to evaluate afterwards
Abc_SclFindNodesToUpdate( pObj, &vRecalcs, &vEvals );
assert( Vec_IntSize(vEvals) > 0 );
//printf( "%d -> %d\n", Vec_IntSize(vRecalcs), Vec_IntSize(vEvals) );
// consider fanouts of this node
fanBest = -1;
gateBest2 = -1;
dGainBest2 = 0;
Abc_NodeCollectFanouts( pBuffer, vFanouts );
Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, j )
{
// skip COs
if ( Abc_ObjIsCo(pFanout) )
continue;
// skip non-critical fanouts
if ( !pFanout->fMarkA )
continue;
// skip if fanin already has fanout as a fanout
if ( Abc_NodeFindFanin(pFanout, pObj) >= 0 )
continue;
// prepare
Abc_SclLoadStore3( p, pBuffer );
Abc_SclUpdateLoadSplit( p, pBuffer, pFanout );
Abc_ObjPatchFanin( pFanout, pBuffer, pObj );
// size the fanin
// save old gate, timing, fanin load // save old gate, timing, fanin load
pCellOld = Abc_SclObjCell( p, pObj ); pCellOld = Abc_SclObjCell( p, pObj );
Abc_SclConeStore( p, vRecalcs ); Abc_SclConeStore( p, vRecalcs );
Abc_SclLoadStore( p, pObj ); Abc_SclLoadStore( p, pObj );
// try different gate sizes for the fanin // try different gate sizes for this node
gateBest = -1; gateBest = -1;
dGainBest = -SC_LibTimeFromPs(p->pLib, (float)DelayGap); dGainBest = -SC_LibTimeFromPs(p->pLib, DelayGap);
SC_RingForEachCell( pCellOld, pCellNew, k ) SC_RingForEachCell( pCellOld, pCellNew, k )
{ {
if ( pCellNew == pCellOld ) if ( pCellNew == pCellOld )
...@@ -328,7 +286,10 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc ...@@ -328,7 +286,10 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
// evaluate gain // evaluate gain
dGain = 0.0; dGain = 0.0;
Abc_NtkForEachObjVec( vEvals, p->pNtk, pTemp, n ) Abc_NtkForEachObjVec( vEvals, p->pNtk, pTemp, n )
dGain += Abc_SclObjGain( p, pTemp ); {
gGainCur = Abc_SclObjGain( p, pTemp );
dGain += (gGainCur > 0) ? gGainCur : 2.0 * gGainCur;
}
dGain /= Vec_IntSize(vEvals); dGain /= Vec_IntSize(vEvals);
// save best gain // save best gain
if ( dGainBest < dGain ) if ( dGainBest < dGain )
...@@ -340,7 +301,87 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc ...@@ -340,7 +301,87 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
// put back old cell and timing // put back old cell and timing
Abc_SclObjSetCell( p, pObj, pCellOld ); Abc_SclObjSetCell( p, pObj, pCellOld );
Abc_SclConeRestore( p, vRecalcs ); Abc_SclConeRestore( p, vRecalcs );
*pGainBest = dGainBest;
return gateBest;
}
/**Function*************************************************************
Synopsis [Computes the set of gates to upsize.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notches, int iIter, int DelayGap, int fVeryVerbose )
{
SC_Cell * pCellOld, * pCellNew;
Vec_Ptr_t * vFanouts;
Vec_Int_t * vRecalcs, * vEvals;
Abc_Obj_t * pBuf, * pFanin, * pFanout, * pExtra = NULL;
int i, j, iNode, gateBest, gateBest2, fanBest, Counter = 0;
float dGainBest, dGainBest2;
// compute savings due to bypassing buffers
vFanouts = Vec_PtrAlloc( 100 );
vRecalcs = Vec_IntAlloc( 100 );
vEvals = Vec_IntAlloc( 100 );
Vec_QueClear( p->vNodeByGain );
Abc_NtkForEachObjVec( vPathNodes, p->pNtk, pBuf, i )
{
assert( pBuf->fMarkC == 0 );
if ( Abc_ObjFaninNum(pBuf) != 1 )
continue;
pFanin = Abc_ObjFanin0(pBuf);
if ( !Abc_ObjIsNode(pFanin) )
continue;
if ( p->pNtk->vPhases == NULL )
{
if ( Abc_SclIsInv(pBuf) )
{
if ( !Abc_ObjIsNode(pFanin) || !Abc_SclIsInv(pFanin) )
continue;
pFanin = Abc_ObjFanin0(pFanin);
if ( !Abc_ObjIsNode(pFanin) )
continue;
pExtra = pBuf;
// we make pBuf and pFanin are in the same phase and pFanin is a node
}
}
// here we have pBuf and its fanin pFanin, which is a logic node
// compute nodes to recalculate timing and nodes to evaluate afterwards
Abc_SclFindNodesToUpdate( pFanin, &vRecalcs, &vEvals, pExtra );
assert( Vec_IntSize(vEvals) > 0 );
// consider fanouts of this node
fanBest = -1;
gateBest2 = -1;
dGainBest2 = 0;
Abc_NodeCollectFanouts( pBuf, vFanouts );
Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, j )
{
// skip COs
if ( Abc_ObjIsCo(pFanout) )
continue;
// skip non-critical fanouts
if ( !pFanout->fMarkA )
continue;
// skip if fanin already has fanout as a fanout
if ( Abc_NodeFindFanin(pFanout, pFanin) >= 0 )
continue;
// prepare
Abc_SclLoadStore3( p, pBuf );
Abc_SclUpdateLoadSplit( p, pBuf, pFanout );
Abc_ObjPatchFanin( pFanout, pBuf, pFanin );
// size the fanin
gateBest = Abc_SclFindBestCell( p, pFanin, vRecalcs, vEvals, Notches, DelayGap, &dGainBest );
// unprepare
Abc_SclLoadRestore3( p, pBuf );
Abc_ObjPatchFanin( pFanout, pFanin, pBuf );
if ( gateBest == -1 )
continue;
// compare gain // compare gain
if ( dGainBest2 < dGainBest ) if ( dGainBest2 < dGainBest )
{ {
...@@ -348,24 +389,18 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc ...@@ -348,24 +389,18 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
gateBest2 = gateBest; gateBest2 = gateBest;
fanBest = Abc_ObjId(pFanout); fanBest = Abc_ObjId(pFanout);
} }
Abc_SclLoadRestore3( p, pBuffer );
Abc_ObjPatchFanin( pFanout, pObj, pBuffer );
} }
// remember savings // remember savings
if ( gateBest2 >= 0 ) if ( gateBest2 >= 0 )
{ {
assert( dGainBest2 > 0.0 ); assert( dGainBest2 > 0.0 );
Vec_FltWriteEntry( p->vNode2Gain, Abc_ObjId(pBuffer), dGainBest2 ); Vec_FltWriteEntry( p->vNode2Gain, Abc_ObjId(pBuf), dGainBest2 );
Vec_IntWriteEntry( p->vNode2Gate, Abc_ObjId(pBuffer), gateBest2 ); Vec_IntWriteEntry( p->vNode2Gate, Abc_ObjId(pBuf), gateBest2 );
Vec_QuePush( p->vNodeByGain, Abc_ObjId(pBuffer) ); Vec_QuePush( p->vNodeByGain, Abc_ObjId(pBuf) );
Vec_IntWriteEntry( p->vBestFans, Abc_ObjId(pBuffer), fanBest ); Vec_IntWriteEntry( p->vBestFans, Abc_ObjId(pBuf), fanBest );
} }
// if ( ++Counter == 17 )
if ( ++Counter == 17 ) // break;
break;
} }
Vec_PtrFree( vFanouts ); Vec_PtrFree( vFanouts );
Vec_IntFree( vRecalcs ); Vec_IntFree( vRecalcs );
...@@ -379,17 +414,17 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc ...@@ -379,17 +414,17 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
vFanouts = Vec_PtrAlloc( 100 ); vFanouts = Vec_PtrAlloc( 100 );
while ( Vec_QueSize(p->vNodeByGain) ) while ( Vec_QueSize(p->vNodeByGain) )
{ {
int iNode = Vec_QuePop(p->vNodeByGain); iNode = Vec_QuePop(p->vNodeByGain);
Abc_Obj_t * pObj = Abc_NtkObj( p->pNtk, iNode ); pFanout = Abc_NtkObj( p->pNtk, Vec_IntEntry(p->vBestFans, iNode) );
Abc_Obj_t * pFanout = Abc_NtkObj( p->pNtk, Vec_IntEntry(p->vBestFans, iNode) ); pBuf = Abc_NtkObj( p->pNtk, iNode );
Abc_Obj_t * pFanin = Abc_ObjFanin0(pObj); pFanin = Abc_ObjFanin0(pBuf);
if ( pObj->fMarkC || pFanout->fMarkC || pFanin->fMarkC ) if ( pFanout->fMarkC || pBuf->fMarkC || pFanin->fMarkC )
continue; continue;
pObj->fMarkC = 1;
pFanout->fMarkC = 1; pFanout->fMarkC = 1;
pBuf->fMarkC = 1;
pFanin->fMarkC = 1; pFanin->fMarkC = 1;
Vec_PtrPush( vFanouts, pObj );
Vec_PtrPush( vFanouts, pFanout ); Vec_PtrPush( vFanouts, pFanout );
Vec_PtrPush( vFanouts, pBuf );
Vec_PtrPush( vFanouts, pFanin ); Vec_PtrPush( vFanouts, pFanin );
// remember gain // remember gain
if ( dGainBest2 == -1 ) if ( dGainBest2 == -1 )
...@@ -397,11 +432,11 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc ...@@ -397,11 +432,11 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
else if ( dGainBest2 > 2*Vec_FltEntry(p->vNode2Gain, iNode) ) else if ( dGainBest2 > 2*Vec_FltEntry(p->vNode2Gain, iNode) )
break; break;
// redirect // redirect
Abc_ObjPatchFanin( pFanout, pObj, pFanin ); Abc_ObjPatchFanin( pFanout, pBuf, pFanin );
// remember // remember
Vec_IntPush( p->vUpdates2, Abc_ObjId(pFanout) ); Vec_IntPush( p->vUpdates2, Abc_ObjId(pFanout) );
Vec_IntPush( p->vUpdates2, Abc_ObjId(pFanin) ); Vec_IntPush( p->vUpdates2, Abc_ObjId(pFanin) );
Vec_IntPush( p->vUpdates2, Abc_ObjId(pObj) ); Vec_IntPush( p->vUpdates2, Abc_ObjId(pBuf) );
// find old and new gates // find old and new gates
pCellOld = Abc_SclObjCell( p, pFanin ); pCellOld = Abc_SclObjCell( p, pFanin );
pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, iNode) ); pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, iNode) );
...@@ -413,23 +448,23 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc ...@@ -413,23 +448,23 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
Vec_IntPush( p->vUpdates, pCellNew->Id ); Vec_IntPush( p->vUpdates, pCellNew->Id );
// remember when this node was upsized // remember when this node was upsized
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanout), 0 ); Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanout), 0 );
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pBuf), 0 );
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanin), 0 ); Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanin), 0 );
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pObj), 0 );
// update polarity // update polarity
if ( p->pNtk->vPhases && Abc_SclIsInv(pObj) ) if ( p->pNtk->vPhases && Abc_SclIsInv(pBuf) )
Abc_NodeInvUpdateObjFanoutPolarity( pFanin, pFanout ); Abc_NodeInvUpdateObjFanoutPolarity( pFanin, pFanout );
// report // report
if ( fVeryVerbose ) if ( fVeryVerbose )
printf( "Node %6d Redir fanout %6d to fanin %6d. Gain = %7.1f ps. Replacing gate %12s by gate %12s.\n", printf( "Node %6d Redir fanout %6d to fanin %6d. Gain = %7.1f ps. Replacing gate %12s by gate %12s.\n",
Abc_ObjId(pObj), Abc_ObjId(pFanout), Abc_ObjId(pFanin), Abc_ObjId(pBuf), Abc_ObjId(pFanout), Abc_ObjId(pFanin),
Vec_FltEntry(p->vNode2Gain, iNode), pCellOld->pName, pCellNew->pName ); Vec_FltEntry(p->vNode2Gain, iNode), pCellOld->pName, pCellNew->pName );
/* /*
// check if the node became useless // check if the node became useless
if ( Abc_ObjFanoutNum(pObj) == 0 ) if ( Abc_ObjFanoutNum(pBuf) == 0 )
{ {
pCellOld = Abc_SclObjCell( p, pObj ); pCellOld = Abc_SclObjCell( p, pBuf );
p->SumArea -= pCellOld->area; p->SumArea -= pCellOld->area;
Abc_NtkDeleteObj_rec( pObj, 1 ); Abc_NtkDeleteObj_rec( pBuf, 1 );
printf( "Removed node %d.\n", iNode ); printf( "Removed node %d.\n", iNode );
} }
*/ */
...@@ -438,32 +473,6 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc ...@@ -438,32 +473,6 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc
Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, j ) Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, j )
pFanout->fMarkC = 0; pFanout->fMarkC = 0;
Vec_PtrFree( vFanouts ); Vec_PtrFree( vFanouts );
/*
Limit = Abc_MinInt( Vec_QueSize(p->vNodeByGain), Abc_MaxInt((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++ )
{
// get the object
pObj = Abc_NtkObj( p->pNtk, Vec_QuePop(p->vNodeByGain) );
assert( pObj->fMarkA );
// find old and new gates
pCellOld = Abc_SclObjCell( p, pObj );
pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, Abc_ObjId(pObj)) );
assert( pCellNew != NULL );
//printf( "%6d %20s -> %20s ", Abc_ObjId(pObj), pCellOld->pName, pCellNew->pName );
//printf( "gain is %f\n", Vec_FltEntry(p->vNode2Gain, Abc_ObjId(pObj)) );
// update gate
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
p->SumArea += pCellNew->area - pCellOld->area;
Abc_SclObjSetCell( p, pObj, pCellNew );
// record the update
Vec_IntPush( p->vUpdates, Abc_ObjId(pObj) );
Vec_IntPush( p->vUpdates, pCellNew->Id );
// remember when this node was upsized
Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pObj), iIter );
}
*/
return Counter; return Counter;
} }
...@@ -533,9 +542,9 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch ...@@ -533,9 +542,9 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
SC_Cell * pCellOld, * pCellNew; SC_Cell * pCellOld, * pCellNew;
Vec_Int_t * vRecalcs, * vEvals; Vec_Int_t * vRecalcs, * vEvals;
Vec_Ptr_t * vFanouts; Vec_Ptr_t * vFanouts;
Abc_Obj_t * pObj, * pTemp; Abc_Obj_t * pObj;
float dGain, dGainBest, dGainBest2; float dGainBest, dGainBest2;
int i, k, n, gateBest, Limit, Counter, iIterLast; int i, gateBest, Limit, Counter, iIterLast;
// compute savings due to upsizing each node // compute savings due to upsizing each node
vRecalcs = Vec_IntAlloc( 100 ); vRecalcs = Vec_IntAlloc( 100 );
...@@ -548,47 +557,10 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch ...@@ -548,47 +557,10 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch
if ( iIterLast >= 0 && iIterLast + 5 > iIter ) if ( iIterLast >= 0 && iIterLast + 5 > iIter )
continue; continue;
// compute nodes to recalculate timing and nodes to evaluate afterwards // compute nodes to recalculate timing and nodes to evaluate afterwards
Abc_SclFindNodesToUpdate( pObj, &vRecalcs, &vEvals ); Abc_SclFindNodesToUpdate( pObj, &vRecalcs, &vEvals, NULL );
assert( Vec_IntSize(vEvals) > 0 ); assert( Vec_IntSize(vEvals) > 0 );
//printf( "%d -> %d\n", Vec_IntSize(vRecalcs), Vec_IntSize(vEvals) ); //printf( "%d -> %d\n", Vec_IntSize(vRecalcs), Vec_IntSize(vEvals) );
// save old gate, timing, fanin load gateBest = Abc_SclFindBestCell( p, pObj, vRecalcs, vEvals, Notches, DelayGap, &dGainBest );
pCellOld = Abc_SclObjCell( p, pObj );
Abc_SclConeStore( p, vRecalcs );
Abc_SclLoadStore( p, pObj );
// try different gate sizes for this node
gateBest = -1;
dGainBest = -SC_LibTimeFromPs(p->pLib, (float)DelayGap);
SC_RingForEachCell( pCellOld, pCellNew, k )
{
if ( pCellNew == pCellOld )
continue;
if ( k > Notches )
break;
if ( p->pInDrive && !Abc_SclInputDriveOk( p, pObj, pCellNew ) )
continue;
// set new cell
Abc_SclObjSetCell( p, pObj, pCellNew );
Abc_SclUpdateLoad( p, pObj, pCellOld, pCellNew );
// 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);
// save best gain
if ( dGainBest < dGain )
{
dGainBest = dGain;
gateBest = pCellNew->Id;
}
}
// put back old cell and timing
Abc_SclObjSetCell( p, pObj, pCellOld );
Abc_SclConeRestore( p, vRecalcs );
// remember savings // remember savings
if ( gateBest >= 0 ) if ( gateBest >= 0 )
{ {
...@@ -819,9 +791,8 @@ void Abc_SclUpsizeRemoveDangling( SC_Man * p, Abc_Ntk_t * pNtk ) ...@@ -819,9 +791,8 @@ void Abc_SclUpsizeRemoveDangling( SC_Man * p, Abc_Ntk_t * pNtk )
pCell = Abc_SclObjCell( p, pObj ); pCell = Abc_SclObjCell( p, pObj );
p->SumArea -= pCell->area; p->SumArea -= pCell->area;
Abc_NtkDeleteObj_rec( pObj, 1 ); Abc_NtkDeleteObj_rec( pObj, 1 );
printf( "Removed node %d.\n", i ); // printf( "Removed node %d.\n", i );
} }
} }
/**Function************************************************************* /**Function*************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment