summaryrefslogtreecommitdiffstats
path: root/src/map/scl/sclTime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/scl/sclTime.c')
-rw-r--r--src/map/scl/sclTime.c366
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 );
}