diff options
Diffstat (limited to 'src/map/scl/sclTime.c')
-rw-r--r-- | src/map/scl/sclTime.c | 366 |
1 files changed, 187 insertions, 179 deletions
diff --git a/src/map/scl/sclTime.c b/src/map/scl/sclTime.c index b78d1b23..55ff7efb 100644 --- a/src/map/scl/sclTime.c +++ b/src/map/scl/sclTime.c @@ -19,6 +19,7 @@ #include "base/abc/abc.h" #include "map/mio/mio.h" #include "sclInt.h" +#include "sclMan.h" ABC_NAMESPACE_IMPL_START @@ -27,40 +28,13 @@ ABC_NAMESPACE_IMPL_START /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// -typedef struct SC_Pair_ SC_Pair; -typedef struct SC_Man_ SC_Man; - -struct SC_Pair_ -{ - float rise; - float fall; -}; - -struct SC_Man_ -{ - SC_Lib * pLib; // library - Abc_Ntk_t * pNtk; // network - int nObjs; // allocated size - Vec_Int_t * vGates; // mapping of objId into gateId - SC_Pair * pLoads; // loads for each gate - SC_Pair * pArrs; // arrivals for each gate - SC_Pair * pSlews; // slews for each gate - char * pWireLoadUsed; // name of the used WireLoad model -}; - -static inline SC_Pair * Abc_SclObjLoad( SC_Man * p, Abc_Obj_t * pObj ) { return p->pLoads + Abc_ObjId(pObj); } -static inline SC_Pair * Abc_SclObjArr ( SC_Man * p, Abc_Obj_t * pObj ) { return p->pArrs + 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_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj ) { return SC_LibCell( p->pLib, Vec_IntEntry(p->vGates, Abc_ObjId(pObj)) ); } - //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* - Synopsis [Prepares STA manager.] + Synopsis [] Description [] @@ -69,45 +43,110 @@ static inline SC_Cell * Abc_SclObjCell( SC_Man * p, Abc_Obj_t * pObj ) { return SeeAlso [] ***********************************************************************/ -void Abc_SclManFindGates( SC_Man * p ) +float Abc_SclTotalArea( SC_Man * p ) { + double Area = 0; Abc_Obj_t * pObj; - char * pName; - int i, gateId; - assert( p->vGates == NULL ); - p->vGates = Vec_IntStartFull( p->nObjs ); + int i; + Abc_NtkForEachNode( p->pNtk, pObj, i ) + Area += Abc_SclObjCell( p, pObj )->area; + return Area; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Abc_SclTimeNtkPrint( SC_Man * p ) +{ + Abc_Obj_t * pObj; + int i; + printf( "Total area = %f.\n", Abc_SclTotalArea( p ) ); + printf( "WireLoad model = \"%s\".\n", p->pWLoadUsed ); Abc_NtkForEachNode( p->pNtk, pObj, i ) { - pName = Mio_GateReadName((Mio_Gate_t *)pObj->pData); - gateId = Abc_SclCellFind( p->pLib, pName ); - assert( gateId >= 0 ); - Vec_IntWriteEntry( p->vGates, i, gateId ); -//printf( "Found gate %s\n", pName ); + printf( "Node %6d : ", Abc_ObjId(pObj) ); + printf( "TimeR = %f. ", Abc_SclObjTime(p, pObj)->rise ); + printf( "RimeF = %f. ", Abc_SclObjTime(p, pObj)->fall ); + printf( "SlewR = %f. ", Abc_SclObjSlew(p, pObj)->rise ); + printf( "SlewF = %f. ", Abc_SclObjSlew(p, pObj)->fall ); + printf( "LoadR = %f. ", Abc_SclObjLoad(p, pObj)->rise ); + printf( "LoadF = %f. ", Abc_SclObjLoad(p, pObj)->fall ); + printf( "\n" ); } } -SC_Man * Abc_SclManAlloc( SC_Lib * pLib, Abc_Ntk_t * pNtk ) +Abc_Obj_t * Abc_SclFindMostCritical( SC_Man * p, int * pfRise ) { - SC_Man * p; - assert( Abc_NtkHasMapping(pNtk) ); - p = ABC_CALLOC( SC_Man, 1 ); - p->pLib = pLib; - p->pNtk = pNtk; - p->nObjs = Abc_NtkObjNumMax(pNtk); - p->pLoads = ABC_CALLOC( SC_Pair, p->nObjs ); - p->pArrs = ABC_CALLOC( SC_Pair, p->nObjs ); - p->pSlews = ABC_CALLOC( SC_Pair, p->nObjs ); - Abc_SclManFindGates( p ); - return p; + Abc_Obj_t * pObj, * pPivot = NULL; + float fMaxArr = 0; + int i; + Abc_NtkForEachCo( p->pNtk, pObj, i ) + { + SC_Pair * pArr = Abc_SclObjTime( p, pObj ); + if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise, *pfRise = 1, pPivot = pObj; + if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall, *pfRise = 0, pPivot = pObj; + } + assert( pPivot != NULL ); + return pPivot; } -void Abc_SclManFree( SC_Man * p ) +Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t * pNode ) { - Vec_IntFree( p->vGates ); - ABC_FREE( p->pLoads ); - ABC_FREE( p->pArrs ); - ABC_FREE( p->pSlews ); - ABC_FREE( p ); + Abc_Obj_t * pObj, * pPivot = NULL; + float fMaxArr = 0; + int i; + Abc_ObjForEachFanin( pNode, pObj, i ) + { + SC_Pair * pArr = Abc_SclObjTime( p, pObj ); + if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise, *pfRise = 1, pPivot = pObj; + if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall, *pfRise = 0, pPivot = pObj; + } + return pPivot; } +Vec_Int_t * Abc_SclCriticalPathFind( SC_Man * p ) +{ + int fRise = 0; + Abc_Obj_t * pPivot = Abc_SclFindMostCritical( p, &fRise ); + Vec_Int_t * vPath = Vec_IntAlloc( 100 ); + Vec_IntPush( vPath, Abc_ObjId(pPivot) ); + pPivot = Abc_ObjFanin0(pPivot); + while ( pPivot && Abc_ObjIsNode(pPivot) ) + { + Vec_IntPush( vPath, Abc_ObjId(pPivot) ); + pPivot = Abc_SclFindMostCriticalFanin( p, &fRise, pPivot ); + } + return vPath; +} +void Abc_SclCriticalPathPrint( SC_Man * p ) +{ + int fRise = 0; + Abc_Obj_t * pPivot = Abc_SclFindMostCritical( p, &fRise ); + printf( "Total area = %10.2f.\n", Abc_SclTotalArea( p ) ); + printf( "WireLoad model = \"%s\".\n", p->pWLoadUsed ); + printf( "Critical delay = %.1f ps\n", Abc_SclObjTimePs(p, pPivot, fRise) ); + + printf( "Critical path: \n" ); + pPivot = Abc_ObjFanin0(pPivot); + while ( pPivot && Abc_ObjIsNode(pPivot) ) + { + printf( "%5d : ", Abc_ObjId(pPivot) ); + printf( "%-10s ", Abc_SclObjCell(p, pPivot)->name ); + printf( "(%s) ", fRise ? "rise" : "fall" ); + printf( "delay =%6.1f ps ", Abc_SclObjTimePs(p, pPivot, fRise) ); + printf( "load =%6.2f ff ", Abc_SclObjLoadFf(p, pPivot, fRise) ); + printf( "slew =%6.1f ps ", Abc_SclObjSlewPs(p, pPivot, fRise) ); + printf( "\n" ); + + pPivot = Abc_SclFindMostCriticalFanin( p, &fRise, pPivot ); + } +} /**Function************************************************************* @@ -121,22 +160,13 @@ void Abc_SclManFree( SC_Man * p ) SeeAlso [] ***********************************************************************/ -float Abc_SclTotalArea( SC_Man * p ) -{ - double Area = 0; - Abc_Obj_t * pObj; - int i; - Abc_NtkForEachNode( p->pNtk, pObj, i ) - Area += Abc_SclObjCell( p, pObj )->area; - return Area; -} Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p ) { Vec_Flt_t * vCaps = NULL; SC_WireLoad * pWL = NULL; int i, Entry, EntryMax; float EntryPrev, EntryCur; - p->pWireLoadUsed = NULL; + p->pWLoadUsed = NULL; if ( p->pLib->default_wire_load_sel && strlen(p->pLib->default_wire_load_sel) ) { float Area; @@ -153,27 +183,27 @@ Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p ) for ( i = 0; i < Vec_FltSize(pWLS->vAreaFrom); i++) if ( Area >= Vec_FltEntry(pWLS->vAreaFrom, i) && Area < Vec_FltEntry(pWLS->vAreaTo, i) ) { - p->pWireLoadUsed = (char *)Vec_PtrEntry(pWLS->vWireLoadModel, i); + p->pWLoadUsed = (char *)Vec_PtrEntry(pWLS->vWireLoadModel, i); break; } if ( i == Vec_FltSize(pWLS->vAreaFrom) ) - p->pWireLoadUsed = (char *)Vec_PtrEntryLast(pWLS->vWireLoadModel); + p->pWLoadUsed = (char *)Vec_PtrEntryLast(pWLS->vWireLoadModel); } else if ( p->pLib->default_wire_load && strlen(p->pLib->default_wire_load) ) - p->pWireLoadUsed = p->pLib->default_wire_load; + p->pWLoadUsed = p->pLib->default_wire_load; else { Abc_Print( 0, "No wire model given.\n" ); return NULL; } // Get the actual table and reformat it for 'wire_cap' output: - assert( p->pWireLoadUsed != NULL ); + assert( p->pWLoadUsed != NULL ); Vec_PtrForEachEntry( SC_WireLoad *, p->pLib->vWireLoads, pWL, i ) - if ( !strcmp(pWL->name, p->pWireLoadUsed) ) + if ( !strcmp(pWL->name, p->pWLoadUsed) ) break; if ( i == Vec_PtrSize(p->pLib->vWireLoadSels) ) { - Abc_Print( -1, "Cannot find wire load model \"%s\".\n", p->pWireLoadUsed ); + Abc_Print( -1, "Cannot find wire load model \"%s\".\n", p->pWLoadUsed ); exit(1); } // find the biggest fanout @@ -195,20 +225,9 @@ Vec_Flt_t * Abc_SclFindWireCaps( SC_Man * p ) } return vCaps; } - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void Abc_SclComputeLoad( SC_Man * p, Vec_Flt_t * vWireCaps ) +void Abc_SclComputeLoad( SC_Man * p ) { + Vec_Flt_t * vWireCaps; Abc_Obj_t * pObj, * pFanin; int i, k; Abc_NtkForEachNode( p->pNtk, pObj, i ) @@ -216,12 +235,13 @@ void Abc_SclComputeLoad( SC_Man * p, Vec_Flt_t * vWireCaps ) SC_Cell * pCell = Abc_SclObjCell( p, pObj ); Abc_ObjForEachFanin( pObj, pFanin, k ) { - SC_Pin * pPin = SC_CellPin( pCell, k ); SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); + SC_Pin * pPin = SC_CellPin( pCell, k ); pLoad->rise += pPin->rise_cap; pLoad->fall += pPin->fall_cap; } } + vWireCaps = Abc_SclFindWireCaps( p ); if ( vWireCaps ) { Abc_NtkForEachNode( p->pNtk, pObj, i ) @@ -232,75 +252,19 @@ void Abc_SclComputeLoad( SC_Man * p, Vec_Flt_t * vWireCaps ) pLoad->fall += Vec_FltEntry(vWireCaps, k); } } + Vec_FltFree( vWireCaps ); } - -/**Function************************************************************* - - Synopsis [] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Abc_Obj_t * Abc_SclFindMostCritical( SC_Man * p, int * pfRise ) -{ - Abc_Obj_t * pObj, * pPivot = NULL; - float fMaxArr = 0; - int i; - Abc_NtkForEachNode( p->pNtk, pObj, i ) - { - SC_Pair * pArr = Abc_SclObjArr( p, pObj ); - if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise, *pfRise = 1, pPivot = pObj; - if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall, *pfRise = 0, pPivot = pObj; - } - assert( pPivot != NULL ); - return pPivot; -} -Abc_Obj_t * Abc_SclFindMostCriticalFanin( SC_Man * p, int * pfRise, Abc_Obj_t * pNode ) -{ - Abc_Obj_t * pObj, * pPivot = NULL; - float fMaxArr = 0; - int i; - Abc_ObjForEachFanin( pNode, pObj, i ) - { - SC_Pair * pArr = Abc_SclObjArr( p, pObj ); - if ( fMaxArr < pArr->rise ) fMaxArr = pArr->rise, *pfRise = 1, pPivot = pObj; - if ( fMaxArr < pArr->fall ) fMaxArr = pArr->fall, *pfRise = 0, pPivot = pObj; - } - assert( pPivot != NULL ); - return pPivot; -} -void Abc_SclCriticalPathPrint( SC_Man * p, Vec_Ptr_t * vNodes ) +void Abc_SclUpdateLoad( SC_Man * p, Abc_Obj_t * pObj, SC_Cell * pOld, SC_Cell * pNew ) { -} -void Abc_SclTimeNtkPrint( SC_Man * p ) -{ -/* - int fRise = 0; - Abc_Obj_t * pPivot = Abc_SclFindMostCritical( p, &fRise, vNodes ); - printf( "Critical delay: ObjId = %d. ", Abc_ObjId(pPivot) ); - printf( "Rise = %f. ", Abc_SclObjArr(p, pPivot)->rise ); - printf( "Fall = %f. ", Abc_SclObjArr(p, pPivot)->fall ); - printf( "\n" ); -*/ - - Abc_Obj_t * pObj; - int i; - printf( "WireLoad model = \"%s\".\n", p->pWireLoadUsed ); - printf( "Area = %f.\n", Abc_SclTotalArea( p ) ); - Abc_NtkForEachNode( p->pNtk, pObj, i ) + Abc_Obj_t * pFanin; + int k; + Abc_ObjForEachFanin( pObj, pFanin, k ) { - printf( "Node %6d : ", Abc_ObjId(pObj) ); - printf( "TimeR = %f. ", Abc_SclObjArr(p, pObj)->rise ); - printf( "RimeF = %f. ", Abc_SclObjArr(p, pObj)->fall ); - printf( "SlewR = %f. ", Abc_SclObjSlew(p, pObj)->rise ); - printf( "SlewF = %f. ", Abc_SclObjSlew(p, pObj)->fall ); - printf( "LoadR = %f. ", Abc_SclObjLoad(p, pObj)->rise ); - printf( "LoadF = %f. ", Abc_SclObjLoad(p, pObj)->fall ); - printf( "\n" ); + SC_Pair * pLoad = Abc_SclObjLoad( p, pFanin ); + SC_Pin * pPinOld = SC_CellPin( pOld, k ); + SC_Pin * pPinNew = SC_CellPin( pNew, k ); + pLoad->rise += pPinNew->rise_cap - pPinOld->rise_cap; + pLoad->fall += pPinNew->fall_cap - pPinOld->fall_cap; } } @@ -346,12 +310,12 @@ static inline float Abc_SclLookup( SC_Surface * p, float slew, float load ) return p0 + sfrac * (p1 - p0); // <<== multiply result with K factor here } -void Abc_SclTimeGate( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) +static inline void Abc_SclTimeGate( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t * pFanin ) { - SC_Pair * pArrIn = Abc_SclObjArr ( p, pFanin ); + SC_Pair * pArrIn = Abc_SclObjTime ( p, pFanin ); SC_Pair * pSlewIn = Abc_SclObjSlew( p, pFanin ); SC_Pair * pLoad = Abc_SclObjLoad( p, pObj ); - SC_Pair * pArrOut = Abc_SclObjArr ( p, pObj ); // modified + SC_Pair * pArrOut = Abc_SclObjTime ( p, pObj ); // modified SC_Pair * pSlewOut = Abc_SclObjSlew( p, pObj ); // modified if (pTime->tsense == sc_ts_Pos || pTime->tsense == sc_ts_Non) @@ -369,36 +333,80 @@ void Abc_SclTimeGate( SC_Man * p, SC_Timing * pTime, Abc_Obj_t * pObj, Abc_Obj_t pSlewOut->fall = Abc_MaxFloat( pSlewOut->fall, Abc_SclLookup(pTime->pFallTrans, pSlewIn->rise, pLoad->fall) ); } } +void Abc_SclTimeObj( SC_Man * p, Abc_Obj_t * pObj ) +{ + SC_Timings * pRTime; + SC_Timing * pTime; + SC_Pin * pPin; + SC_Cell * pCell; + int k; + if ( Abc_ObjIsCo(pObj) ) + { + Abc_SclObjDupFanin( p, pObj ); + return; + } + assert( Abc_ObjIsNode(pObj) ); + // get the library cell + pCell = Abc_SclObjCell( p, pObj ); + // get the output pin + assert( pCell->n_outputs == 1 ); + pPin = SC_CellPin( pCell, pCell->n_inputs ); + // compute timing using each fanin + assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs ); + Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k ) + { + assert( Vec_PtrSize(pRTime->vTimings) == 1 ); + pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); + Abc_SclTimeGate( p, pTime, pObj, Abc_ObjFanin(pObj, k) ); + } +} void Abc_SclTimeNtk( SC_Man * p ) { - Vec_Flt_t * vWireCaps; Abc_Obj_t * pObj; - int i, k; - vWireCaps = Abc_SclFindWireCaps( p ); - Abc_SclComputeLoad( p, vWireCaps ); + int i; Abc_NtkForEachNode( p->pNtk, pObj, i ) + Abc_SclTimeObj( p, pObj ); + Abc_NtkForEachCo( p->pNtk, pObj, i ) + Abc_SclObjDupFanin( p, pObj ); +} +void Abc_SclTimeCone( SC_Man * p, Vec_Int_t * vCone ) +{ + Abc_Obj_t * pObj; + int i; + Abc_NtkForEachObjVec( vCone, p->pNtk, pObj, i ) { - SC_Timings * pRTime; - SC_Timing * pTime; - SC_Pin * pPin; - // get the library cell - SC_Cell * pCell = Abc_SclObjCell( p, pObj ); - // get the output pin - assert( pCell->n_outputs == 1 ); - pPin = SC_CellPin( pCell, pCell->n_inputs ); - // compute timing using each fanin - assert( Vec_PtrSize(pPin->vRTimings) == pCell->n_inputs ); - Vec_PtrForEachEntry( SC_Timings *, pPin->vRTimings, pRTime, k ) - { - assert( Vec_PtrSize(pRTime->vTimings) == 1 ); - pTime = (SC_Timing *)Vec_PtrEntry( pRTime->vTimings, 0 ); - Abc_SclTimeGate( p, pTime, pObj, Abc_ObjFanin(pObj, k) ); - } + if ( Abc_ObjIsNode(pObj) ) + printf( " Updating node with gate %s\n", Abc_SclObjCell(p, pObj)->name ); + + printf( " before %6.1f ps ", Abc_SclObjTimePs(p, pObj, 0) ); + Abc_SclTimeObj( p, pObj ); + printf( "after %6.1f ps\n", Abc_SclObjTimePs(p, pObj, 0) ); } - Abc_SclTimeNtkPrint( p ); - Vec_FltFree( vWireCaps ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +SC_Man * Abc_SclManStart( SC_Lib * pLib, Abc_Ntk_t * pNtk ) +{ + extern Vec_Int_t * Abc_SclManFindGates( SC_Lib * pLib, Abc_Ntk_t * p ); + // prepare timing manager + SC_Man * p = Abc_SclManAlloc( pLib, pNtk ); + assert( p->vGates == NULL ); + p->vGates = Abc_SclManFindGates( pLib, pNtk ); + p->SumArea = Abc_SclTotalArea( p ); + Abc_SclComputeLoad( p ); + Abc_SclTimeNtk( p ); + return p; +} /**Function************************************************************* @@ -414,8 +422,8 @@ void Abc_SclTimeNtk( SC_Man * p ) void Abc_SclTimePerform( SC_Lib * pLib, void * pNtk ) { SC_Man * p; - p = Abc_SclManAlloc( pLib, (Abc_Ntk_t *)pNtk ); - Abc_SclTimeNtk( p ); + p = Abc_SclManStart( pLib, (Abc_Ntk_t *)pNtk ); + Abc_SclCriticalPathPrint( p ); Abc_SclManFree( p ); } |