From d4ad3b4156dd2d4fa6d56573e606b05c2d2d97f9 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Fri, 9 Aug 2013 19:47:58 -0700 Subject: Improvements to buffering and sizing. --- src/base/abci/abc.c | 6 ++++++ src/base/abci/abcTiming.c | 2 +- src/map/scl/sclDnsize.c | 2 +- src/map/scl/sclLib.c | 8 ++++++-- src/map/scl/sclLoad.c | 30 +++++++++++++++--------------- src/map/scl/sclSize.c | 42 ++++++++++++++++++++++++++++++++++++++---- src/map/scl/sclSize.h | 9 ++++++++- src/map/scl/sclUpsize.c | 39 +++++++++++++++++++++++++++++++++------ 8 files changed, 108 insertions(+), 30 deletions(-) diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index 76c604bb..e48886be 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -19626,6 +19626,12 @@ int Abc_CommandCec( Abc_Frame_t * pAbc, int argc, char ** argv ) } } + if ( pNtk->vPhases != NULL ) + { + Abc_Print( -1, "Cannot compare networks with phases defined.\n" ); + return 1; + } + pArgvNew = argv + globalUtilOptind; nArgcNew = argc - globalUtilOptind; if ( !Abc_NtkPrepareTwoNtks( stdout, pNtk, pArgvNew, nArgcNew, &pNtk1, &pNtk2, &fDelete1, &fDelete2 ) ) diff --git a/src/base/abci/abcTiming.c b/src/base/abci/abcTiming.c index e4dd9503..50d2a9b7 100644 --- a/src/base/abci/abcTiming.c +++ b/src/base/abci/abcTiming.c @@ -1053,7 +1053,7 @@ int Abc_ObjLevelNew( Abc_Obj_t * pObj ) int i, Level = 0; Abc_ObjForEachFanin( pObj, pFanin, i ) Level = Abc_MaxFloat( Level, Abc_ObjLevel(pFanin) ); - return Level + 1; + return Level + (int)(Abc_ObjFaninNum(pObj) > 0); } /**Function************************************************************* diff --git a/src/map/scl/sclDnsize.c b/src/map/scl/sclDnsize.c index 511659c1..4bc21d28 100644 --- a/src/map/scl/sclDnsize.c +++ b/src/map/scl/sclDnsize.c @@ -296,7 +296,7 @@ void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars Vec_QuePush( p->vNodeByGain, Abc_ObjId(pObj) ); clk = Abc_Clock(); - if ( p->nIncUpdates ) + if ( Vec_IntSize(p->vChanged) ) Abc_SclTimeIncUpdate( p ); else Abc_SclTimeNtkRecompute( p, &p->SumArea, &p->MaxDelay, pPars->fUseDept, pPars->DelayUser ); diff --git a/src/map/scl/sclLib.c b/src/map/scl/sclLib.c index a2d5b16a..1dfdcd13 100644 --- a/src/map/scl/sclLib.c +++ b/src/map/scl/sclLib.c @@ -741,9 +741,13 @@ static int Abc_SclCompareCells( SC_Cell ** pp1, SC_Cell ** pp2 ) return -1; if ( (*pp1)->n_inputs > (*pp2)->n_inputs ) return 1; - if ( (*pp1)->area < (*pp2)->area ) +// if ( (*pp1)->area < (*pp2)->area ) +// return -1; +// if ( (*pp1)->area > (*pp2)->area ) +// return 1; + if ( SC_CellPinCapAve(*pp1) < SC_CellPinCapAve(*pp2) ) return -1; - if ( (*pp1)->area > (*pp2)->area ) + if ( SC_CellPinCapAve(*pp1) > SC_CellPinCapAve(*pp2) ) return 1; return strcmp( (*pp1)->pName, (*pp2)->pName ); } diff --git a/src/map/scl/sclLoad.c b/src/map/scl/sclLoad.c index 10b5d8f1..fd932dd1 100644 --- a/src/map/scl/sclLoad.c +++ b/src/map/scl/sclLoad.c @@ -79,9 +79,19 @@ Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p, SC_WireLoad * pWL ) SeeAlso [] ***********************************************************************/ +static inline float Abc_SclFindWireLoad( SC_Man * p, Abc_Obj_t * pObj ) +{ + int nFans = Abc_MinInt( Vec_FltSize(p->vWireCaps)-1, Abc_ObjFanoutNum(pObj) ); + return p->vWireCaps ? Vec_FltEntry(p->vWireCaps, nFans) : 0; +} +void Abc_SclAddWireLoad( SC_Man * p, Abc_Obj_t * pObj, int fSubtr ) +{ + float Load = Abc_SclFindWireLoad( p, pObj ); + Abc_SclObjLoad(p, pObj)->rise += fSubtr ? -Load : Load; + Abc_SclObjLoad(p, pObj)->fall += fSubtr ? -Load : Load; +} void Abc_SclComputeLoad( SC_Man * p ) { - Vec_Flt_t * vWireCaps; Abc_Obj_t * pObj, * pFanin; int i, k; // clear load storage @@ -114,22 +124,12 @@ void Abc_SclComputeLoad( SC_Man * p ) // add wire load if ( p->pWLoadUsed != NULL ) { - vWireCaps = Abc_SclFindWireCaps( p, p->pWLoadUsed ); + if ( p->vWireCaps == NULL ) + p->vWireCaps = Abc_SclFindWireCaps( p, p->pWLoadUsed ); Abc_NtkForEachNode1( p->pNtk, pObj, i ) - { - SC_Pair * pLoad = Abc_SclObjLoad( p, pObj ); - k = Abc_MinInt( Vec_FltSize(vWireCaps)-1, Abc_ObjFanoutNum(pObj) ); - pLoad->rise += Vec_FltEntry(vWireCaps, k); - pLoad->fall += Vec_FltEntry(vWireCaps, k); - } + Abc_SclAddWireLoad( p, pObj, 0 ); Abc_NtkForEachPi( p->pNtk, pObj, i ) - { - SC_Pair * pLoad = Abc_SclObjLoad( p, pObj ); - k = Abc_MinInt( Vec_FltSize(vWireCaps)-1, Abc_ObjFanoutNum(pObj) ); - pLoad->rise += Vec_FltEntry(vWireCaps, k); - pLoad->fall += Vec_FltEntry(vWireCaps, k); - } - Vec_FltFree( vWireCaps ); + Abc_SclAddWireLoad( p, pObj, 0 ); } // check input loads if ( p->vInDrive != NULL ) diff --git a/src/map/scl/sclSize.c b/src/map/scl/sclSize.c index 82d4fa39..fcc32da9 100644 --- a/src/map/scl/sclSize.c +++ b/src/map/scl/sclSize.c @@ -435,13 +435,32 @@ static inline void Abc_SclTimeIncUpdateDeparture( SC_Man * p ) if ( !SC_PairEqualE(&DepOut, pDepOut, E) ) Abc_SclTimeIncAddFanins( p, pObj ); } - } + } p->MaxDelay = Abc_SclReadMaxDelay( p ); } +void Abc_SclTimeIncCheckLevel( Abc_Ntk_t * pNtk ) +{ + Abc_Obj_t * pObj; + int i; + Abc_NtkForEachObj( pNtk, pObj, i ) + if ( (int)pObj->Level != Abc_ObjLevelNew(pObj) ) + printf( "Level of node %d is out of date!\n", i ); +} void Abc_SclTimeIncUpdate( SC_Man * p ) { - if ( p->nIncUpdates == 0 ) + Abc_Obj_t * pObj; + int i; + if ( Vec_IntSize(p->vChanged) == 0 ) return; +// Abc_SclTimeIncCheckLevel( p->pNtk ); + Abc_NtkForEachObjVec( p->vChanged, p->pNtk, pObj, i ) + { + if ( pObj->fMarkC ) + continue; + Abc_SclTimeIncAddFanins( p, pObj ); + Abc_SclTimeIncAddNode( p, pObj ); + } + Vec_IntClear( p->vChanged ); Abc_SclTimeIncUpdateArrival( p ); Abc_SclTimeIncUpdateDeparture( p ); Abc_SclTimeIncUpdateClean( p ); @@ -449,10 +468,25 @@ void Abc_SclTimeIncUpdate( SC_Man * p ) } void Abc_SclTimeIncInsert( SC_Man * p, Abc_Obj_t * pObj ) { - Abc_SclTimeIncAddFanins( p, pObj ); - Abc_SclTimeIncAddNode( p, pObj ); + Vec_IntPush( p->vChanged, Abc_ObjId(pObj) ); +} +void Abc_SclTimeIncUpdateLevel_rec( Abc_Obj_t * pObj ) +{ + Abc_Obj_t * pFanout; + int i, LevelNew = Abc_ObjLevelNew(pObj); + if ( LevelNew == (int)pObj->Level ) + return; + pObj->Level = LevelNew; + Abc_ObjForEachFanout( pObj, pFanout, i ) + Abc_SclTimeIncUpdateLevel_rec( pFanout ); +} +void Abc_SclTimeIncUpdateLevel( Abc_Obj_t * pObj ) +{ + Abc_SclTimeIncUpdateLevel_rec( pObj ); } + + /**Function************************************************************* Synopsis [Read input slew and output load.] diff --git a/src/map/scl/sclSize.h b/src/map/scl/sclSize.h index a01aac83..eeade9bc 100644 --- a/src/map/scl/sclSize.h +++ b/src/map/scl/sclSize.h @@ -53,6 +53,7 @@ struct SC_Man_ Vec_Int_t * vUpdates2; // sizing updates in this round // timing information SC_WireLoad * pWLoadUsed; // name of the used WireLoad model + Vec_Flt_t * vWireCaps; // wire capacitances SC_Pair * pLoads; // loads for each gate SC_Pair * pDepts; // departures for each gate SC_Pair * pTimes; // arrivals for each gate @@ -78,6 +79,7 @@ struct SC_Man_ Vec_Int_t * vBestFans; // best fanouts // incremental timing update Vec_Wec_t * vLevels; + Vec_Int_t * vChanged; int nIncUpdates; // optimization parameters float SumArea; // total area @@ -174,8 +176,9 @@ static inline SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk ) Vec_QueSetCosts( p->vNodeByGain, Vec_FltArrayP(p->vNode2Gain) ); p->vNodeIter = Vec_IntStartFull( p->nObjs ); p->vLevels = Vec_WecStart( 2 * Abc_NtkLevel(pNtk) ); + p->vChanged = Vec_IntAlloc( 100 ); Abc_NtkForEachCo( pNtk, pObj, i ) - pObj->Level = Abc_ObjFanin0(pObj)->Level; + pObj->Level = Abc_ObjFanin0(pObj)->Level + 1; // set CI/CO ids Abc_NtkForEachCi( pNtk, pObj, i ) pObj->iData = i; @@ -200,12 +203,14 @@ static inline void Abc_SclManFree( SC_Man * p ) Vec_IntFreeP( &p->vUpdates2 ); Vec_IntFreeP( &p->vGatesBest ); Vec_WecFreeP( &p->vLevels ); + Vec_IntFreeP( &p->vChanged ); // Vec_QuePrint( p->vQue ); Vec_QueCheck( p->vQue ); Vec_QueFreeP( &p->vQue ); Vec_FltFreeP( &p->vTimesOut ); Vec_IntFreeP( &p->vBestFans ); Vec_FltFreeP( &p->vInDrive ); + Vec_FltFreeP( &p->vWireCaps ); ABC_FREE( p->pLoads ); ABC_FREE( p->pDepts ); ABC_FREE( p->pTimes ); @@ -495,6 +500,7 @@ extern Abc_Ntk_t * Abc_SclBufPerform( Abc_Ntk_t * pNtk, int FanMin, int FanMax /*=== sclDnsize.c ===============================================================*/ extern void Abc_SclDnsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars ); /*=== sclLoad.c ===============================================================*/ +extern void Abc_SclAddWireLoad( SC_Man * p, Abc_Obj_t * pObj, int fSubtr ); extern void Abc_SclComputeLoad( SC_Man * p ); extern void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew ); extern void Abc_SclUpdateLoadSplit( SC_Man * p, Abc_Obj_t * pBuffer, Abc_Obj_t * pFanout ); @@ -507,6 +513,7 @@ extern void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone ); extern void Abc_SclTimeNtkRecompute( SC_Man * p, float * pArea, float * pDelay, int fReverse, float DUser ); extern void 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_SclPrintBuffers( SC_Lib * pLib, Abc_Ntk_t * pNtk, int fVerbose ); extern int Abc_SclInputDriveOk( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pCell ); diff --git a/src/map/scl/sclUpsize.c b/src/map/scl/sclUpsize.c index a3294ebb..9f9b23ce 100644 --- a/src/map/scl/sclUpsize.c +++ b/src/map/scl/sclUpsize.c @@ -436,7 +436,24 @@ int Abc_SclFindBypasses( SC_Man * p, Vec_Int_t * vPathNodes, int Ratio, int Notc pFanout = Abc_NtkObj( p->pNtk, Vec_IntEntry(p->vBestFans, iNode) ); pBuf = Abc_NtkObj( p->pNtk, iNode ); pFanin = Abc_ObjFanin0(pBuf); - assert( p->pNtk->vPhases == NULL ); // problem! + if ( p->pNtk->vPhases == NULL ) + { + // update fanin + if ( Abc_SclIsInv(pBuf) ) + { + if ( !Abc_ObjIsNode(pFanin) || !Abc_SclIsInv(pFanin) ) + { + assert( 0 ); + continue; + } + pFanin = Abc_ObjFanin0(pFanin); + if ( !Abc_ObjIsNode(pFanin) ) + { + assert( 0 ); + continue; + } + } + } if ( pFanout->fMarkB || pBuf->fMarkB || pFanin->fMarkB ) continue; pFanout->fMarkB = 1; @@ -451,21 +468,28 @@ 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_SclUpdateLoadSplit( p, pBuf, pFanout ); + Abc_SclAddWireLoad( p, pBuf, 1 ); + Abc_SclAddWireLoad( p, pFanin, 1 ); Abc_ObjPatchFanin( pFanout, pBuf, pFanin ); + Abc_SclAddWireLoad( p, pBuf, 0 ); + Abc_SclAddWireLoad( p, pFanin, 0 ); + Abc_SclTimeIncUpdateLevel( pFanout ); // remember Vec_IntPush( p->vUpdates2, Abc_ObjId(pFanout) ); Vec_IntPush( p->vUpdates2, Abc_ObjId(pFanin) ); Vec_IntPush( p->vUpdates2, Abc_ObjId(pBuf) ); - // find old and new gates + // update cell pCellOld = Abc_SclObjCell( pFanin ); pCellNew = SC_LibCell( p->pLib, Vec_IntEntry(p->vNode2Gate, iNode) ); - // update cell p->SumArea += pCellNew->area - pCellOld->area; Abc_SclObjSetCell( pFanin, pCellNew ); Abc_SclUpdateLoad( p, pFanin, pCellOld, pCellNew ); // record the update Vec_IntPush( p->vUpdates, Abc_ObjId(pFanin) ); Vec_IntPush( p->vUpdates, pCellNew->Id ); + Abc_SclTimeIncInsert( p, pFanout ); + Abc_SclTimeIncInsert( p, pBuf ); Abc_SclTimeIncInsert( p, pFanin ); // remember when this node was upsized Vec_IntWriteEntry( p->vNodeIter, Abc_ObjId(pFanout), -1 ); @@ -691,11 +715,11 @@ void Abc_SclUndoRecentChanges( Abc_Ntk_t * pNtk, Vec_Int_t * vTrans ) Abc_Obj_t * pFanout = Abc_NtkObj( pNtk, Vec_IntEntry(vTrans, 3*i+0) ); Abc_Obj_t * pFanin = Abc_NtkObj( pNtk, Vec_IntEntry(vTrans, 3*i+1) ); Abc_Obj_t * pObj = Abc_NtkObj( pNtk, Vec_IntEntry(vTrans, 3*i+2) ); + // we do not update load here because times will be recomputed Abc_ObjPatchFanin( pFanout, pFanin, pObj ); - + Abc_SclTimeIncUpdateLevel( pFanout ); // printf( "Node %6d Redir fanout %6d from fanin %6d. \n", // Abc_ObjId(pObj), Abc_ObjId(pFanout), Abc_ObjId(pFanin) ); - // update polarity if ( pNtk->vPhases && Abc_SclIsInv(pObj) ) Abc_NodeInvUpdateObjFanoutPolarity( pObj, pFanout ); @@ -902,8 +926,11 @@ void Abc_SclUpsizePerform( SC_Lib * pLib, Abc_Ntk_t * pNtk, SC_SizePars * pPars if ( pPars->fUseDept ) { vTFO = Vec_IntAlloc( 0 ); - if ( p->nIncUpdates ) + if ( Vec_IntSize(p->vChanged) )//&& pPars->BypassFreq == 0 ) + { +// Abc_SclComputeLoad( p ); Abc_SclTimeIncUpdate( p ); + } else Abc_SclTimeNtkRecompute( p, NULL, NULL, pPars->fUseDept, 0 ); } -- cgit v1.2.3