summaryrefslogtreecommitdiffstats
path: root/src/base/abc/abcTiming.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/abc/abcTiming.c')
-rw-r--r--src/base/abc/abcTiming.c631
1 files changed, 631 insertions, 0 deletions
diff --git a/src/base/abc/abcTiming.c b/src/base/abc/abcTiming.c
new file mode 100644
index 00000000..f017d93c
--- /dev/null
+++ b/src/base/abc/abcTiming.c
@@ -0,0 +1,631 @@
+/**CFile****************************************************************
+
+ FileName [abcTiming.c]
+
+ SystemName [ABC: Logic synthesis and verification system.]
+
+ PackageName [Network and node package.]
+
+ Synopsis [Computation of timing info for mapped circuits.]
+
+ Author [Alan Mishchenko]
+
+ Affiliation [UC Berkeley]
+
+ Date [Ver. 1.0. Started - June 20, 2005.]
+
+ Revision [$Id: abcTiming.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
+
+***********************************************************************/
+
+#include "abc.h"
+#include "main.h"
+#include "mio.h"
+
+////////////////////////////////////////////////////////////////////////
+/// DECLARATIONS ///
+////////////////////////////////////////////////////////////////////////
+
+struct Abc_ManTime_t_
+{
+ Abc_Time_t tArrDef;
+ Abc_Time_t tReqDef;
+ Vec_Ptr_t * vArrs;
+ Vec_Ptr_t * vReqs;
+};
+
+// static functions
+static Abc_ManTime_t * Abc_ManTimeStart();
+static void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive );
+static void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk );
+
+static 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 pNode->pNtk->pManTime->vArrs->pArray[pNode->Id]; }
+static inline Abc_Time_t * Abc_NodeRequired( Abc_Obj_t * pNode ) { return pNode->pNtk->pManTime->vReqs->pArray[pNode->Id]; }
+
+////////////////////////////////////////////////////////////////////////
+/// FUNCTION DEFITIONS ///
+////////////////////////////////////////////////////////////////////////
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NodeReadArrival( Abc_Obj_t * pNode )
+{
+ assert( pNode->pNtk->pManTime );
+ return Abc_NodeArrival(pNode);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NodeReadRequired( Abc_Obj_t * pNode )
+{
+ assert( pNode->pNtk->pManTime );
+ return Abc_NodeRequired(pNode);
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NtkReadDefaultArrival( Abc_Ntk_t * pNtk )
+{
+ assert( pNtk->pManTime );
+ return &pNtk->pManTime->tArrDef;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Reads the arrival time of the node.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NtkReadDefaultRequired( Abc_Ntk_t * pNtk )
+{
+ assert( pNtk->pManTime );
+ return &pNtk->pManTime->tReqDef;
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the default arrival time for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetDefaultArrival( Abc_Ntk_t * pNtk, float Rise, float Fall )
+{
+ if ( Rise == 0.0 && Fall == 0.0 )
+ return;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ pNtk->pManTime->tArrDef.Rise = Rise;
+ pNtk->pManTime->tArrDef.Fall = Fall;
+ pNtk->pManTime->tArrDef.Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the default arrival time for the network.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetDefaultRequired( Abc_Ntk_t * pNtk, float Rise, float Fall )
+{
+ if ( Rise == 0.0 && Fall == 0.0 )
+ return;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ pNtk->pManTime->tReqDef.Rise = Rise;
+ pNtk->pManTime->tReqDef.Rise = Fall;
+ pNtk->pManTime->tReqDef.Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the arrival time for an object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetArrival( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall )
+{
+ Vec_Ptr_t * vTimes;
+ Abc_Time_t * pTime;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ if ( pNtk->pManTime->tArrDef.Rise == Rise && pNtk->pManTime->tArrDef.Fall == Fall )
+ return;
+ Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 );
+ // set the arrival time
+ vTimes = pNtk->pManTime->vArrs;
+ pTime = vTimes->pArray[ObjId];
+ pTime->Rise = Rise;
+ pTime->Fall = Rise;
+ pTime->Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the arrival time for an object.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeSetRequired( Abc_Ntk_t * pNtk, int ObjId, float Rise, float Fall )
+{
+ Vec_Ptr_t * vTimes;
+ Abc_Time_t * pTime;
+ if ( pNtk->pManTime == NULL )
+ pNtk->pManTime = Abc_ManTimeStart();
+ if ( pNtk->pManTime->tReqDef.Rise == Rise && pNtk->pManTime->tReqDef.Fall == Fall )
+ return;
+ Abc_ManTimeExpand( pNtk->pManTime, ObjId + 1, 1 );
+ // set the required time
+ vTimes = pNtk->pManTime->vReqs;
+ pTime = vTimes->pArray[ObjId];
+ pTime->Rise = Rise;
+ pTime->Fall = Rise;
+ pTime->Worst = ABC_MAX( Rise, Fall );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Finalizes the timing manager after setting arr/req times.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimeFinalize( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ Abc_Time_t ** ppTimes, * pTime;
+ int i;
+ if ( pNtk->pManTime == NULL )
+ return;
+ Abc_ManTimeExpand( pNtk->pManTime, Abc_NtkObjNum(pNtk), 0 );
+ // set the default timing
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
+ Abc_NtkForEachPi( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ if ( pTime->Worst != -ABC_INFINITY )
+ continue;
+ *pTime = pNtk->pManTime->tArrDef;
+ }
+ // set the default timing
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vReqs->pArray;
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ if ( pTime->Worst != -ABC_INFINITY )
+ continue;
+ *pTime = pNtk->pManTime->tArrDef;
+ }
+ // set the 0 arrival times for latches and constant nodes
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
+ Abc_NtkForEachLatch( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ pTime->Fall = pTime->Rise = pTime->Worst = 0.0;
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Prepares the timing manager for delay trace.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkTimePrepare( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pObj;
+ Abc_Time_t ** ppTimes, * pTime;
+ int i;
+ // if there is no timing manager, allocate and initialize
+ if ( pNtk->pManTime == NULL )
+ {
+ pNtk->pManTime = Abc_ManTimeStart();
+ Abc_NtkTimeFinalize( pNtk );
+ return;
+ }
+ // if timing manager is given, clean arrivals except for PIs
+ // and required except for POs
+ ppTimes = (Abc_Time_t **)pNtk->pManTime->vArrs->pArray;
+ Abc_NtkForEachNode( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
+ }
+ Abc_NtkForEachPo( pNtk, pObj, i )
+ {
+ pTime = ppTimes[pObj->Id];
+ pTime->Fall = pTime->Rise = pTime->Worst = -ABC_INFINITY;
+ }
+}
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_ManTime_t * Abc_ManTimeStart()
+{
+ Abc_ManTime_t * p;
+ p = ALLOC( Abc_ManTime_t, 1 );
+ memset( p, 0, sizeof(Abc_ManTime_t) );
+ p->vArrs = Vec_PtrAlloc( 0 );
+ p->vReqs = Vec_PtrAlloc( 0 );
+ return p;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManTimeStop( Abc_ManTime_t * p )
+{
+ if ( p->vArrs->nSize > 0 )
+ {
+ free( p->vArrs->pArray[0] );
+ Vec_PtrFree( p->vArrs );
+ }
+ if ( p->vReqs->nSize > 0 )
+ {
+ free( p->vReqs->pArray[0] );
+ Vec_PtrFree( p->vReqs );
+ }
+ free( p );
+}
+
+/**Function*************************************************************
+
+ Synopsis [Duplicates the timing manager with the PI/PO timing info.]
+
+ Description [The PIs/POs of the new network should be allocated.]
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManTimeDup( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew )
+{
+ Abc_Obj_t * pObj;
+ Abc_Time_t ** ppTimesOld, ** ppTimesNew;
+ int i;
+ if ( pNtkOld->pManTime == NULL )
+ return;
+ assert( Abc_NtkPiNum(pNtkOld) == Abc_NtkPiNum(pNtkNew) );
+ assert( Abc_NtkPoNum(pNtkOld) == Abc_NtkPoNum(pNtkNew) );
+ assert( Abc_NtkLatchNum(pNtkOld) == Abc_NtkLatchNum(pNtkNew) );
+ // create the new timing manager
+ pNtkNew->pManTime = Abc_ManTimeStart();
+ Abc_ManTimeExpand( pNtkNew->pManTime, Abc_NtkObjNum(pNtkNew), 0 );
+ // set the default timing
+ pNtkNew->pManTime->tArrDef = pNtkOld->pManTime->tArrDef;
+ pNtkNew->pManTime->tReqDef = pNtkOld->pManTime->tReqDef;
+ // set the PI timing
+ ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vArrs->pArray;
+ ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vArrs->pArray;
+ Abc_NtkForEachPi( pNtkOld, pObj, i )
+ *ppTimesNew[ Abc_NtkPi(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
+ // set the PO timing
+ ppTimesOld = (Abc_Time_t **)pNtkOld->pManTime->vReqs->pArray;
+ ppTimesNew = (Abc_Time_t **)pNtkNew->pManTime->vReqs->pArray;
+ Abc_NtkForEachPo( pNtkOld, pObj, i )
+ *ppTimesNew[ Abc_NtkPo(pNtkNew,i)->Id ] = *ppTimesOld[ pObj->Id ];
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_ManTimeExpand( Abc_ManTime_t * p, int nSize, int fProgressive )
+{
+ Vec_Ptr_t * vTimes;
+ Abc_Time_t * ppTimes, * ppTimesOld, * pTime;
+ int nSizeOld, nSizeNew, i;
+
+ nSizeOld = p->vArrs->nSize;
+ if ( nSizeOld >= nSize )
+ return;
+ nSizeNew = fProgressive? 2 * nSize : nSize;
+ if ( nSizeNew < 100 )
+ nSizeNew = 100;
+
+ vTimes = p->vArrs;
+ Vec_PtrGrow( vTimes, nSizeNew );
+ vTimes->nSize = nSizeNew;
+ ppTimesOld = ( nSizeOld == 0 )? NULL : vTimes->pArray[0];
+ ppTimes = REALLOC( Abc_Time_t, ppTimesOld, nSizeNew );
+ for ( i = 0; i < nSizeNew; i++ )
+ vTimes->pArray[i] = ppTimes + i;
+ for ( i = nSizeOld; i < nSizeNew; i++ )
+ {
+ pTime = vTimes->pArray[i];
+ pTime->Rise = -ABC_INFINITY;
+ pTime->Fall = -ABC_INFINITY;
+ pTime->Worst = -ABC_INFINITY;
+ }
+
+ vTimes = p->vReqs;
+ Vec_PtrGrow( vTimes, nSizeNew );
+ vTimes->nSize = nSizeNew;
+ ppTimesOld = ( nSizeOld == 0 )? NULL : vTimes->pArray[0];
+ ppTimes = REALLOC( Abc_Time_t, ppTimesOld, nSizeNew );
+ for ( i = 0; i < nSizeNew; i++ )
+ vTimes->pArray[i] = ppTimes + i;
+ for ( i = nSizeOld; i < nSizeNew; i++ )
+ {
+ pTime = vTimes->pArray[i];
+ pTime->Rise = -ABC_INFINITY;
+ pTime->Fall = -ABC_INFINITY;
+ pTime->Worst = -ABC_INFINITY;
+ }
+}
+
+
+
+
+
+
+/**Function*************************************************************
+
+ Synopsis [Sets the CI node levels according to the arrival info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NtkSetNodeLevelsArrival( Abc_Ntk_t * pNtkOld )
+{
+ Abc_Obj_t * pNodeOld, * pNodeNew;
+ float tAndDelay;
+ int i;
+ if ( pNtkOld->pManTime == NULL )
+ return;
+ if ( Mio_LibraryReadNand2(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame())) == NULL )
+ return;
+ tAndDelay = Mio_LibraryReadDelayNand2Max(Abc_FrameReadLibGen(Abc_FrameGetGlobalFrame()));
+ Abc_NtkForEachPi( pNtkOld, pNodeOld, i )
+ {
+ pNodeNew = pNodeOld->pCopy;
+ pNodeNew->Level = (int)(Abc_NodeArrival(pNodeOld)->Worst / tAndDelay);
+ }
+}
+
+/**Function*************************************************************
+
+ Synopsis [Sets the CI node levels according to the arrival info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+Abc_Time_t * Abc_NtkGetCiArrivalTimes( Abc_Ntk_t * pNtk )
+{
+ Abc_Time_t * p;
+ Abc_Obj_t * pNode;
+ int i;
+ p = ALLOC( Abc_Time_t, Abc_NtkCiNum(pNtk) );
+ memset( p, 0, sizeof(Abc_Time_t) * Abc_NtkCiNum(pNtk) );
+ if ( pNtk->pManTime == NULL )
+ return p;
+ // set the PI arrival times
+ Abc_NtkForEachPi( pNtk, pNode, i )
+ p[i] = *Abc_NodeArrival(pNode);
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis [Sets the CI node levels according to the arrival info.]
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float * Abc_NtkGetCiArrivalFloats( Abc_Ntk_t * pNtk )
+{
+ float * p;
+ Abc_Obj_t * pNode;
+ int i;
+ p = ALLOC( float, Abc_NtkCiNum(pNtk) );
+ memset( p, 0, sizeof(float) * Abc_NtkCiNum(pNtk) );
+ if ( pNtk->pManTime == NULL )
+ return p;
+ // set the PI arrival times
+ Abc_NtkForEachPi( pNtk, pNode, i )
+ p[i] = Abc_NodeArrival(pNode)->Worst;
+ return p;
+}
+
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+float Abc_NtkDelayTrace( Abc_Ntk_t * pNtk )
+{
+ Abc_Obj_t * pNode, * pDriver;
+ Vec_Ptr_t * vNodes;
+ Abc_Time_t * pTime;
+ float tArrivalMax;
+ int i;
+
+ assert( Abc_NtkIsLogicMap(pNtk) );
+
+ Abc_NtkTimePrepare( pNtk );
+ vNodes = Abc_NtkDfs( pNtk );
+ for ( i = 0; i < vNodes->nSize; i++ )
+ Abc_NodeDelayTraceArrival( vNodes->pArray[i] );
+ 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;
+ }
+ return tArrivalMax;
+}
+
+/**Function*************************************************************
+
+ Synopsis []
+
+ Description []
+
+ SideEffects []
+
+ SeeAlso []
+
+***********************************************************************/
+void Abc_NodeDelayTraceArrival( Abc_Obj_t * pNode )
+{
+ Abc_Obj_t * pFanin;
+ Abc_Time_t * pTimeIn, * pTimeOut;
+ float tDelayBlockRise, tDelayBlockFall;
+ Mio_PinPhase_t PinPhase;
+ Mio_Pin_t * pPin;
+ int i;
+
+ // start the arrival time of the node
+ pTimeOut = Abc_NodeArrival(pNode);
+ pTimeOut->Rise = pTimeOut->Fall = 0;
+ // go through the pins of the gate
+ pPin = Mio_GateReadPins(pNode->pData);
+ Abc_ObjForEachFanin( pNode, pFanin, i )
+ {
+ pTimeIn = Abc_NodeArrival(pFanin);
+ assert( pTimeIn->Worst != -ABC_INFINITY );
+ // 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
+ 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;
+ }
+ 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;
+ }
+ pPin = Mio_PinReadNext(pPin);
+ }
+ pTimeOut->Worst = ABC_MAX( pTimeOut->Rise, pTimeOut->Fall );
+}
+
+////////////////////////////////////////////////////////////////////////
+/// END OF FILE ///
+////////////////////////////////////////////////////////////////////////
+
+