summaryrefslogtreecommitdiffstats
path: root/src/base/abci/abcTiming.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/abci/abcTiming.c')
-rw-r--r--src/base/abci/abcTiming.c297
1 files changed, 274 insertions, 23 deletions
diff --git a/src/base/abci/abcTiming.c b/src/base/abci/abcTiming.c
index a9b50563..3f47b241 100644
--- a/src/base/abci/abcTiming.c
+++ b/src/base/abci/abcTiming.c
@@ -41,8 +41,6 @@ struct Abc_ManTime_t_
static Abc_ManTime_t * Abc_ManTimeStart();
static void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive );
-void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode );
-
// accessing the arrival and required times of a node
static inline Abc_Time_t * Abc_NodeArrival( Abc_Obj_t * pNode ) { return (Abc_Time_t *)pNode->pNtk->pManTime->vArrs->pArray[pNode->Id]; }
static inline Abc_Time_t * Abc_NodeRequired( Abc_Obj_t * pNode ) { return (Abc_Time_t *)pNode->pNtk->pManTime->vReqs->pArray[pNode->Id]; }
@@ -121,6 +119,38 @@ Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk )
/**Function*************************************************************
+ Synopsis [Reads average arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Abc_NodeReadArrivalAve( Abc_Obj_t * pNode )
+{
+ return 0.5 * Abc_NodeArrival(pNode)->Rise + 0.5 * Abc_NodeArrival(pNode)->Fall;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads average required time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Abc_NodeReadRequiredAve( Abc_Obj_t * pNode )
+{
+ return 0.5 * Abc_NodeReadRequired(pNode)->Rise + 0.5 * Abc_NodeReadRequired(pNode)->Fall;
+}
+
+/**Function*************************************************************
+
Synopsis [Sets the default arrival time for the network.]
Description []
@@ -246,6 +276,7 @@ void Abc_NtkTimeInitialize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkOld )
{
pNtk->pManTime->tArrDef = pNtkOld->pManTime->tArrDef;
pNtk->pManTime->tReqDef = pNtkOld->pManTime->tReqDef;
+ pNtk->AndGateDelay = pNtkOld->AndGateDelay;
}
// set the default timing
ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
@@ -492,7 +523,7 @@ void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtkOld )
int i;
if ( pNtkOld->pManTime == NULL )
return;
- if ( Mio_LibraryReadNand2((Mio_Library_t *)Abc_FrameReadLibGen()) == NULL )
+ if ( Abc_FrameReadLibGen() == NULL || Mio_LibraryReadNand2((Mio_Library_t *)Abc_FrameReadLibGen()) == NULL )
return;
tAndDelay = Mio_LibraryReadDelayNand2Max((Mio_Library_t *)Abc_FrameReadLibGen());
Abc_NtkForEachPi( pNtkOld, pNodeOld, i )
@@ -590,32 +621,105 @@ float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk )
+Vec_Int_t * Abc_NtkDelayTraceSlackStart( Abc_Ntk_t * pNtk )
{
- Abc_Obj_t * pNode, * pDriver;
- Vec_Ptr_t * vNodes;
- Abc_Time_t * pTime;
- float tArrivalMax;
+ Vec_Int_t * vSlacks;
+ Abc_Obj_t * pObj;
+ int i, k;
+ vSlacks = Vec_IntAlloc( Abc_NtkObjNumMax(pNtk) + Abc_NtkGetTotalFanins(pNtk) );
+ Vec_IntFill( vSlacks, Abc_NtkObjNumMax(pNtk), -1 );
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ Vec_IntWriteEntry( vSlacks, i, Vec_IntSize(vSlacks) );
+ for ( k = 0; k < Abc_ObjFaninNum(pObj); k++ )
+ Vec_IntPush( vSlacks, -1 );
+ }
+ assert( Vec_IntSize(vSlacks) == Vec_IntCap(vSlacks) );
+ return vSlacks;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Read/write edge slacks.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+static inline float Abc_NtkDelayTraceSlack( Vec_Int_t * vSlacks, Abc_Obj_t * pObj, int iFanin )
+{
+ return Abc_Int2Float( Vec_IntEntry( vSlacks, Vec_IntEntry(vSlacks, Abc_ObjId(pObj)) + iFanin ) );
+}
+static inline void Abc_NtkDelayTraceSetSlack( Vec_Int_t * vSlacks, Abc_Obj_t * pObj, int iFanin, float Num )
+{
+ Vec_IntWriteEntry( vSlacks, Vec_IntEntry(vSlacks, Abc_ObjId(pObj)) + iFanin, Abc_Float2Int(Num) );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Find most-critical path (the path with smallest slacks).]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+int Abc_NtkDelayTraceCritPath_rec( Vec_Int_t * vSlacks, Abc_Obj_t * pNode, Abc_Obj_t * pLeaf, Vec_Int_t * vBest )
+{
+ Abc_Obj_t * pFanin, * pFaninBest = NULL;
+ float SlackMin = ABC_INFINITY;
int i;
+ // check primary inputs
+ if ( Abc_ObjIsCi(pNode) )
+ return (pLeaf == NULL || pLeaf == pNode);
+ assert( Abc_ObjIsNode(pNode) );
+ // check visited
+ if ( Abc_NodeIsTravIdCurrent( pNode ) )
+ return Vec_IntEntry(vBest, Abc_ObjId(pNode)) >= 0;
+ Abc_NodeSetTravIdCurrent( pNode );
+ // check the node
+ assert( Abc_ObjIsNode(pNode) );
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ if ( !Abc_NtkDelayTraceCritPath_rec( vSlacks, pFanin, pLeaf, vBest ) )
+ continue;
+ if ( pFaninBest == NULL || SlackMin > Abc_NtkDelayTraceSlack(vSlacks, pNode, i) )
+ {
+ pFaninBest = pFanin;
+ SlackMin = Abc_NtkDelayTraceSlack(vSlacks, pNode, i);
+ }
+ }
+ if ( pFaninBest != NULL )
+ Vec_IntWriteEntry( vBest, Abc_ObjId(pNode), Abc_NodeFindFanin(pNode, pFaninBest) );
+ return (pFaninBest != NULL);
+}
- assert( Abc_NtkIsMappedLogic(pNtk) );
+/**Function*************************************************************
- Abc_NtkTimePrepare( pNtk );
- vNodes = Abc_NtkDfs( pNtk, 1 );
- for ( i = 0; i < vNodes->nSize; i++ )
- Abc_NodeDelayTraceArrival( (Abc_Obj_t *)vNodes->pArray[i] );
- Vec_PtrFree( vNodes );
+ Synopsis [Find most-critical path (the path with smallest slacks).]
- // get the latest arrival times
- tArrivalMax = -ABC_INFINITY;
- Abc_NtkForEachCo( pNtk, pNode, i )
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkDelayTraceCritPathCollect_rec( Vec_Int_t * vSlacks, Abc_Obj_t * pNode, Vec_Int_t * vBest, Vec_Ptr_t * vPath )
+{
+ assert( Abc_ObjIsCi(pNode) || Abc_ObjIsNode(pNode) );
+ if ( Abc_ObjIsNode(pNode) )
{
- pDriver = Abc_ObjFanin0(pNode);
- pTime = Abc_NodeArrival(pDriver);
- if ( tArrivalMax < pTime->Worst )
- tArrivalMax = pTime->Worst;
+ int iFanin = Vec_IntEntry( vBest, Abc_ObjId(pNode) );
+ assert( iFanin >= 0 );
+ Abc_NtkDelayTraceCritPathCollect_rec( vSlacks, Abc_ObjFanin(pNode, iFanin), vBest, vPath );
}
- return tArrivalMax;
+ Vec_PtrPush( vPath, pNode );
}
/**Function*************************************************************
@@ -629,7 +733,7 @@ float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk )
SeeAlso []
***********************************************************************/
-void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode )
+void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode, Vec_Int_t * vSlacks )
{
Abc_Obj_t * pFanin;
Abc_Time_t * pTimeIn, * pTimeOut;
@@ -668,9 +772,156 @@ void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode )
pPin = Mio_PinReadNext(pPin);
}
pTimeOut->Worst = Abc_MaxFloat( pTimeOut->Rise, pTimeOut->Fall );
+
+ // compute edge slacks
+ if ( vSlacks )
+ {
+ float Slack;
+ // go through the pins of the gate
+ pPin = Mio_GateReadPins((Mio_Gate_t *)pNode->pData);
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ pTimeIn = Abc_NodeArrival(pFanin);
+ // get the interesting parameters of this pin
+ PinPhase = Mio_PinReadPhase(pPin);
+ tDelayBlockRise = (float)Mio_PinReadDelayBlockRise( pPin );
+ tDelayBlockFall = (float)Mio_PinReadDelayBlockFall( pPin );
+ // compute the arrival times of the positive phase
+ Slack = ABC_INFINITY;
+ if ( PinPhase != MIO_PHASE_INV ) // NONINV phase is present
+ {
+// if ( pTimeOut->Rise < pTimeIn->Rise + tDelayBlockRise )
+// pTimeOut->Rise = pTimeIn->Rise + tDelayBlockRise;
+// if ( pTimeOut->Fall < pTimeIn->Fall + tDelayBlockFall )
+// pTimeOut->Fall = pTimeIn->Fall + tDelayBlockFall;
+ Slack = Abc_MinFloat( Slack, Abc_AbsFloat(pTimeIn->Rise + tDelayBlockRise - pTimeOut->Rise) );
+ Slack = Abc_MinFloat( Slack, Abc_AbsFloat(pTimeIn->Fall + tDelayBlockFall - pTimeOut->Fall) );
+ }
+ if ( PinPhase != MIO_PHASE_NONINV ) // INV phase is present
+ {
+// if ( pTimeOut->Rise < pTimeIn->Fall + tDelayBlockRise )
+// pTimeOut->Rise = pTimeIn->Fall + tDelayBlockRise;
+// if ( pTimeOut->Fall < pTimeIn->Rise + tDelayBlockFall )
+// pTimeOut->Fall = pTimeIn->Rise + tDelayBlockFall;
+ Slack = Abc_MinFloat( Slack, Abc_AbsFloat(pTimeIn->Fall + tDelayBlockRise - pTimeOut->Rise) );
+ Slack = Abc_MinFloat( Slack, Abc_AbsFloat(pTimeIn->Rise + tDelayBlockFall - pTimeOut->Fall) );
+ }
+ pPin = Mio_PinReadNext(pPin);
+ Abc_NtkDelayTraceSetSlack( vSlacks, pNode, i, Slack );
+ }
+ }
}
+/**Function*************************************************************
+
+ Synopsis [Performs delay-trace of the network. If input (pIn) or
+ output (pOut) are given, finds the most-timing-critical path between
+ them and prints it to the standard output. If input and/or output are
+ not given, finds the most-critical path in the network and prints it.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk, Abc_Obj_t * pOut, Abc_Obj_t * pIn, int fPrint )
+{
+ Vec_Int_t * vSlacks = NULL;
+ Abc_Obj_t * pNode, * pDriver;
+ Vec_Ptr_t * vNodes;
+ Abc_Time_t * pTime;
+ float tArrivalMax;
+ int i;
+
+ assert( Abc_NtkIsMappedLogic(pNtk) );
+ assert( pOut == NULL || Abc_ObjIsCo(pOut) );
+ assert( pIn == NULL || Abc_ObjIsCi(pIn) );
+
+ // create slacks (need slacks if printing is requested even if pIn/pOut are not given)
+ if ( pOut || pIn || fPrint )
+ vSlacks = Abc_NtkDelayTraceSlackStart( pNtk );
+
+ // compute the timing
+ Abc_NtkTimePrepare( pNtk );
+ vNodes = Abc_NtkDfs( pNtk, 1 );
+ Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
+ Abc_NodeDelayTraceArrival( pNode, vSlacks );
+ Vec_PtrFree( vNodes );
+
+ // get the latest arrival times
+ tArrivalMax = -ABC_INFINITY;
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ pDriver = Abc_ObjFanin0(pNode);
+ pTime = Abc_NodeArrival(pDriver);
+ if ( tArrivalMax < pTime->Worst )
+ tArrivalMax = pTime->Worst;
+ }
+
+ // determine the output to print
+ if ( fPrint && pOut == NULL )
+ {
+ Abc_NtkForEachCo( pNtk, pNode, i )
+ {
+ pDriver = Abc_ObjFanin0(pNode);
+ pTime = Abc_NodeArrival(pDriver);
+ if ( tArrivalMax == pTime->Worst )
+ pOut = pNode;
+ }
+ assert( pOut != NULL );
+ }
+
+ if ( fPrint )
+ {
+ Vec_Ptr_t * vPath = Vec_PtrAlloc( 100 );
+ Vec_Int_t * vBest = Vec_IntStartFull( Abc_NtkObjNumMax(pNtk) );
+ // traverse to determine the critical path
+ Abc_NtkIncrementTravId( pNtk );
+ if ( !Abc_NtkDelayTraceCritPath_rec( vSlacks, Abc_ObjFanin0(pOut), pIn, vBest ) )
+ printf( "There is no combinational path between PO \"%s\" and PI \"%s\".\n", Abc_ObjName(pOut), Abc_ObjName(pIn) );
+ else
+ {
+ // collect the critical path
+ Abc_NtkDelayTraceCritPathCollect_rec( vSlacks, Abc_ObjFanin0(pOut), vBest, vPath );
+ if ( pIn == NULL )
+ pIn = (Abc_Obj_t *)Vec_PtrEntry( vPath, 0 );
+ // print critical path
+ printf( "Critical path to PO \"%s\" from PI \"%s\":\n", Abc_ObjName(pOut), Abc_ObjName(pIn) );
+ Vec_PtrForEachEntryReverse( Abc_Obj_t *, vPath, pNode, i )
+ {
+
+ printf( "Obj =%7d. ", Abc_ObjId(pNode) );
+ printf( "Lev =%4d. ", Abc_ObjLevel(pNode) );
+ printf( " " );
+ printf( "Rise =%6.1f. ", Abc_NodeReadArrival(pNode)->Rise );
+ printf( "Fall =%6.1f. ", Abc_NodeReadArrival(pNode)->Fall );
+ printf( " " );
+ if ( Abc_ObjIsCi(pNode) )
+ printf( "Primary input \"%s\".", Abc_ObjName(pNode) );
+ else if ( Abc_ObjIsCo(pNode) )
+ printf( "Primary output \"%s\".", Abc_ObjName(pNode) );
+ else
+ {
+ int iFanin;
+ assert( Abc_ObjIsNode(pNode) );
+ iFanin = Abc_NodeFindFanin( pNode, (Abc_Obj_t *)Vec_PtrEntry(vPath,i-1) );
+ printf( "Slack =%6.1f. ", Abc_NtkDelayTraceSlack(vSlacks, pNode, iFanin) );
+ printf( "Mapping: Pin = %d. Gate = %s. ", iFanin, Mio_GateReadName(pNode->pData) );
+ }
+ printf( "\n" );
+ }
+ }
+ Vec_PtrFree( vPath );
+ Vec_IntFree( vBest );
+ }
+
+ Vec_IntFreeP( &vSlacks );
+ return tArrivalMax;
+}
+
/**Function*************************************************************