From 655dc4e727e2c4e74cc511f343007cee5b8e35b6 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Wed, 7 Aug 2013 12:32:33 -0700 Subject: Improvements to buffering and sizing. --- src/map/scl/sclSize.h | 44 +++++--- src/map/scl/sclUpsize.c | 287 ++++++++++++++++++++++-------------------------- 2 files changed, 159 insertions(+), 172 deletions(-) diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h index 1f97bc8a..9660cbe9 100644 --- a/src/map/scl/sclSize.h +++ b/src/map/scl/sclSize.h @@ -53,13 +53,13 @@ struct SC_Man_ Vec_Int_t * vUpdates2; // sizing updates in this round // timing information 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 * pTimes; // arrivals for each gate SC_Pair * pSlews; // slews for each gate SC_Pair * pTimes2; // arrivals 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 * pInDrive; // maximum input drive strength Vec_Int_t * vBestFans; // best fanouts @@ -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 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_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); } @@ -153,8 +151,6 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk ) p->pNtk = pNtk; p->nObjs = Abc_NtkObjNumMax(pNtk); 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->pTimes = 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 ) Vec_QuePush( p->vQue, i ); p->vUpdates = Vec_IntAlloc( 1000 ); p->vUpdates2 = Vec_IntAlloc( 1000 ); + p->vLoads2 = Vec_FltAlloc( 1000 ); + p->vLoads3 = Vec_FltAlloc( 1000 ); // intermediate data p->vNode2Gain = Vec_FltStart( p->nObjs ); p->vNode2Gate = Vec_IntStart( p->nObjs ); @@ -184,6 +182,8 @@ static inline void Abc_SclManFree( SC_Man * p ) Vec_FltFreeP( &p->vNode2Gain ); Vec_IntFreeP( &p->vNode2Gate ); // intermediate data + Vec_FltFreeP( &p->vLoads2 ); + Vec_FltFreeP( &p->vLoads3 ); Vec_IntFreeP( &p->vUpdates ); Vec_IntFreeP( &p->vUpdates2 ); Vec_IntFreeP( &p->vGatesBest ); @@ -194,8 +194,6 @@ static inline void Abc_SclManFree( SC_Man * p ) Vec_IntFreeP( &p->vGates ); Vec_IntFreeP( &p->vBestFans ); ABC_FREE( p->pLoads ); - ABC_FREE( p->pLoads2 ); - ABC_FREE( p->pLoads3 ); ABC_FREE( p->pDepts ); ABC_FREE( p->pTimes ); ABC_FREE( p->pSlews ); @@ -288,32 +286,50 @@ static inline void Abc_SclLoadStore( SC_Man * p, Abc_Obj_t * pObj ) { Abc_Obj_t * pFanin; int i; + Vec_FltClear( p->vLoads2 ); 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 ) { Abc_Obj_t * pFanin; int i; + assert( Vec_FltSize(p->vLoads2) == 2 * Abc_ObjFaninNum(pObj) ); 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 ) { Abc_Obj_t * pFanin; int i; - *Abc_SclObjLoad3(p, pObj) = *Abc_SclObjLoad(p, pObj); + Vec_FltClear( p->vLoads3 ); 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 ) { Abc_Obj_t * pFanin; 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_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************************************************************* diff --git a/src/map/scl/sclUpsize.c b/src/map/scl/sclUpsize.c index 5891fb55..9cc8d370 100644 --- a/src/map/scl/sclUpsize.c +++ b/src/map/scl/sclUpsize.c @@ -193,7 +193,7 @@ void Abc_SclUnmarkCriticalNodeWindow( SC_Man * p, Vec_Int_t * vPath ) 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_Obj_t * pObj, * pNext, * pNext2; @@ -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 ) Vec_IntPush( vNodes, Abc_ObjId(pNext) ); Vec_IntPush( vNodes, Abc_ObjId(pPivot) ); + if ( pExtra ) + Vec_IntPush( vNodes, Abc_ObjId(pExtra) ); Abc_ObjForEachFanout( pPivot, pNext, i ) if ( Abc_ObjIsNode(pNext) && pNext->fMarkA ) { @@ -241,6 +243,68 @@ void Abc_SclFindNodesToUpdate( Abc_Obj_t * pPivot, Vec_Int_t ** pvNodes, Vec_Int } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +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; + Abc_Obj_t * pTemp; + float dGain, dGainBest, gGainCur; + int k, n, gateBest; + // save old gate, timing, fanin load + 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, 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 ) + { + gGainCur = Abc_SclObjGain( p, pTemp ); + dGain += (gGainCur > 0) ? gGainCur : 2.0 * gGainCur; + } + 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 ); + *pGainBest = dGainBest; + return gateBest; +} + /**Function************************************************************* Synopsis [Computes the set of gates to upsize.] @@ -257,35 +321,45 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc SC_Cell * pCellOld, * pCellNew; Vec_Ptr_t * vFanouts; Vec_Int_t * vRecalcs, * vEvals; - Abc_Obj_t * pObj, * pTemp, * pBuffer, * pFanout; - float dGain, dGainBest, dGainBest2; - int i, j, k, n, gateBest, gateBest2, fanBest, Counter = 0; + 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, pBuffer, i ) + Abc_NtkForEachObjVec( vPathNodes, p->pNtk, pBuf, i ) { - assert( pBuffer->fMarkC == 0 ); - if ( Abc_ObjFaninNum(pBuffer) != 1 ) + assert( pBuf->fMarkC == 0 ); + if ( Abc_ObjFaninNum(pBuf) != 1 ) continue; - pObj = Abc_ObjFanin0(pBuffer); - if ( !Abc_ObjIsNode(pObj) ) + pFanin = Abc_ObjFanin0(pBuf); + if ( !Abc_ObjIsNode(pFanin) ) continue; - // here we have pBuffer and its fanin pObj, which is a logic node - + 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( pObj, &vRecalcs, &vEvals ); + Abc_SclFindNodesToUpdate( pFanin, &vRecalcs, &vEvals, pExtra ); 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 ); + fanBest = -1; + gateBest2 = -1; + dGainBest2 = 0; + Abc_NodeCollectFanouts( pBuf, vFanouts ); Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, j ) { // skip COs @@ -295,52 +369,19 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc if ( !pFanout->fMarkA ) continue; // skip if fanin already has fanout as a fanout - if ( Abc_NodeFindFanin(pFanout, pObj) >= 0 ) + if ( Abc_NodeFindFanin(pFanout, pFanin) >= 0 ) continue; // prepare - Abc_SclLoadStore3( p, pBuffer ); - Abc_SclUpdateLoadSplit( p, pBuffer, pFanout ); - Abc_ObjPatchFanin( pFanout, pBuffer, pObj ); + Abc_SclLoadStore3( p, pBuf ); + Abc_SclUpdateLoadSplit( p, pBuf, pFanout ); + Abc_ObjPatchFanin( pFanout, pBuf, pFanin ); // size the fanin - // save old gate, timing, fanin load - pCellOld = Abc_SclObjCell( p, pObj ); - Abc_SclConeStore( p, vRecalcs ); - Abc_SclLoadStore( p, pObj ); - // try different gate sizes for the fanin - 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 ); - + 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 if ( dGainBest2 < dGainBest ) { @@ -348,24 +389,18 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc gateBest2 = gateBest; fanBest = Abc_ObjId(pFanout); } - - Abc_SclLoadRestore3( p, pBuffer ); - Abc_ObjPatchFanin( pFanout, pObj, pBuffer ); } - // remember savings if ( gateBest2 >= 0 ) { assert( dGainBest2 > 0.0 ); - Vec_FltWriteEntry( p->vNode2Gain, Abc_ObjId(pBuffer), dGainBest2 ); - Vec_IntWriteEntry( p->vNode2Gate, Abc_ObjId(pBuffer), gateBest2 ); - Vec_QuePush( p->vNodeByGain, Abc_ObjId(pBuffer) ); - Vec_IntWriteEntry( p->vBestFans, Abc_ObjId(pBuffer), fanBest ); + Vec_FltWriteEntry( p->vNode2Gain, Abc_ObjId(pBuf), dGainBest2 ); + Vec_IntWriteEntry( p->vNode2Gate, Abc_ObjId(pBuf), gateBest2 ); + Vec_QuePush( p->vNodeByGain, Abc_ObjId(pBuf) ); + Vec_IntWriteEntry( p->vBestFans, Abc_ObjId(pBuf), fanBest ); } - - if ( ++Counter == 17 ) - break; - +// if ( ++Counter == 17 ) +// break; } Vec_PtrFree( vFanouts ); Vec_IntFree( vRecalcs ); @@ -379,17 +414,17 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc vFanouts = Vec_PtrAlloc( 100 ); while ( Vec_QueSize(p->vNodeByGain) ) { - int iNode = Vec_QuePop(p->vNodeByGain); - Abc_Obj_t * pObj = Abc_NtkObj( p->pNtk, iNode ); - Abc_Obj_t * pFanout = Abc_NtkObj( p->pNtk, Vec_IntEntry(p->vBestFans, iNode) ); - Abc_Obj_t * pFanin = Abc_ObjFanin0(pObj); - if ( pObj->fMarkC || pFanout->fMarkC || pFanin->fMarkC ) + iNode = Vec_QuePop(p->vNodeByGain); + pFanout = Abc_NtkObj( p->pNtk, Vec_IntEntry(p->vBestFans, iNode) ); + pBuf = Abc_NtkObj( p->pNtk, iNode ); + pFanin = Abc_ObjFanin0(pBuf); + if ( pFanout->fMarkC || pBuf->fMarkC || pFanin->fMarkC ) continue; - pObj->fMarkC = 1; pFanout->fMarkC = 1; + pBuf->fMarkC = 1; pFanin->fMarkC = 1; - Vec_PtrPush( vFanouts, pObj ); Vec_PtrPush( vFanouts, pFanout ); + Vec_PtrPush( vFanouts, pBuf ); Vec_PtrPush( vFanouts, pFanin ); // remember gain if ( dGainBest2 == -1 ) @@ -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) ) break; // redirect - Abc_ObjPatchFanin( pFanout, pObj, pFanin ); + Abc_ObjPatchFanin( pFanout, pBuf, pFanin ); // remember Vec_IntPush( p->vUpdates2, Abc_ObjId(pFanout) ); 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 pCellOld = Abc_SclObjCell( p, pFanin ); 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 Vec_IntPush( p->vUpdates, pCellNew->Id ); // remember when this node was upsized 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(pObj), 0 ); // update polarity - if ( p->pNtk->vPhases && Abc_SclIsInv(pObj) ) + if ( p->pNtk->vPhases && Abc_SclIsInv(pBuf) ) Abc_NodeInvUpdateObjFanoutPolarity( pFanin, pFanout ); // report if ( fVeryVerbose ) 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 ); /* // 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; - Abc_NtkDeleteObj_rec( pObj, 1 ); + Abc_NtkDeleteObj_rec( pBuf, 1 ); printf( "Removed node %d.\n", iNode ); } */ @@ -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 ) pFanout->fMarkC = 0; 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; } @@ -533,9 +542,9 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch SC_Cell * pCellOld, * pCellNew; Vec_Int_t * vRecalcs, * vEvals; Vec_Ptr_t * vFanouts; - Abc_Obj_t * pObj, * pTemp; - float dGain, dGainBest, dGainBest2; - int i, k, n, gateBest, Limit, Counter, iIterLast; + Abc_Obj_t * pObj; + float dGainBest, dGainBest2; + int i, gateBest, Limit, Counter, iIterLast; // compute savings due to upsizing each node vRecalcs = Vec_IntAlloc( 100 ); @@ -548,47 +557,10 @@ int Abc_SclFindUpsizes( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notch if ( iIterLast >= 0 && iIterLast + 5 > iIter ) continue; // 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 ); //printf( "%d -> %d\n", Vec_IntSize(vRecalcs), Vec_IntSize(vEvals) ); - // save old gate, timing, fanin load - 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 ); + gateBest = Abc_SclFindBestCell( p, pObj, vRecalcs, vEvals, Notches, DelayGap, &dGainBest ); // remember savings if ( gateBest >= 0 ) { @@ -819,9 +791,8 @@ void Abc_SclUpsizeRemoveDangling( SC_Man * p, Abc_Ntk_t * pNtk ) pCell = Abc_SclObjCell( p, pObj ); p->SumArea -= pCell->area; Abc_NtkDeleteObj_rec( pObj, 1 ); - printf( "Removed node %d.\n", i ); +// printf( "Removed node %d.\n", i ); } - } /**Function************************************************************* -- cgit v1.2.3