ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
nwkTiming.c File Reference
#include "nwk.h"
Include dependency graph for nwkTiming.c:

Go to the source code of this file.

Functions

ABC_NAMESPACE_IMPL_START void Nwk_ManCleanTiming (Nwk_Man_t *pNtk)
 DECLARATIONS ///.
 
void Nwk_ManDelayTraceSortPins (Nwk_Obj_t *pNode, int *pPinPerm, float *pPinDelays)
 
int Nwk_ManWhereIsPin (Nwk_Obj_t *pFanout, Nwk_Obj_t *pFanin, int *pPinPerm)
 
float Nwk_NodeComputeArrival (Nwk_Obj_t *pObj, int fUseSorting)
 
float Nwk_NodeComputeRequired (Nwk_Obj_t *pObj, int fUseSorting)
 
float Nwk_NodePropagateRequired (Nwk_Obj_t *pObj, int fUseSorting)
 
float Nwk_ManDelayTraceLut (Nwk_Man_t *pNtk)
 
int Nwk_ManVerifyTiming (Nwk_Man_t *pNtk)
 
void Nwk_ManDelayTracePrint (Nwk_Man_t *pNtk)
 
void Nwk_NodeUpdateAddToQueue (Vec_Ptr_t *vQueue, Nwk_Obj_t *pObj, int iCurrent, int fArrival)
 
void Nwk_NodeUpdateArrival (Nwk_Obj_t *pObj)
 
void Nwk_NodeUpdateRequired (Nwk_Obj_t *pObj)
 
int Nwk_ObjLevelNew (Nwk_Obj_t *pObj)
 
void Nwk_ManUpdateLevel (Nwk_Obj_t *pObj)
 
int Nwk_ManVerifyLevel (Nwk_Man_t *pNtk)
 
void Nwk_ManUpdate (Nwk_Obj_t *pObj, Nwk_Obj_t *pObjNew, Vec_Vec_t *vLevels)
 

Function Documentation

◆ Nwk_ManCleanTiming()

ABC_NAMESPACE_IMPL_START void Nwk_ManCleanTiming ( Nwk_Man_t * pNtk)

DECLARATIONS ///.

CFile****************************************************************

FileName [nwkTiming.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [Logic network representation.]

Synopsis [Manipulation of timing information.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - June 20, 2005.]

Revision [

Id
nwkTiming.c,v 1.00 2005/06/20 00:00:00 alanmi Exp

] FUNCTION DEFINITIONS /// Function*************************************************************

Synopsis [Cleans timing information for all nodes.]

Description []

SideEffects []

SeeAlso []

Definition at line 45 of file nwkTiming.c.

46{
47 Nwk_Obj_t * pObj;
48 int i;
49 Nwk_ManForEachObj( pNtk, pObj, i )
50 {
51 pObj->tArrival = pObj->tSlack = 0.0;
52 pObj->tRequired = TIM_ETERNITY;
53 }
54}
typedefABC_NAMESPACE_HEADER_START struct Nwk_Obj_t_ Nwk_Obj_t
INCLUDES ///.
Definition nwk.h:49
#define Nwk_ManForEachObj(p, pObj, i)
Definition nwk.h:189
#define TIM_ETERNITY
MACRO DEFINITIONS ///.
Definition tim.h:98
Here is the caller graph for this function:

◆ Nwk_ManDelayTraceLut()

float Nwk_ManDelayTraceLut ( Nwk_Man_t * pNtk)

Function*************************************************************

Synopsis [Computes the delay trace of the given network.]

Description []

SideEffects []

SeeAlso []

Definition at line 326 of file nwkTiming.c.

327{
328 Vec_Ptr_t * vObjs;
329 int fUseSorting = 1;
330 If_LibLut_t * pLutLib = pNtk->pLutLib;
331 Vec_Ptr_t * vNodes;
332 Nwk_Obj_t * pObj;
333 float tArrival, tRequired, tSlack;
334 int i;
335
336 // get the library
337 if ( pLutLib && pLutLib->LutMax < Nwk_ManGetFaninMax(pNtk) )
338 {
339 printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
340 pLutLib->LutMax, Nwk_ManGetFaninMax(pNtk) );
341 return -TIM_ETERNITY;
342 }
343
344 // compute the reverse order of all objects
345 vNodes = Nwk_ManDfsReverse( pNtk );
346
347 // initialize the arrival times
348 Nwk_ManCleanTiming( pNtk );
349
350 // propagate arrival times
351 if ( pNtk->pManTime )
353// Nwk_ManForEachObj( pNtk, pObj, i )
354 vObjs = Nwk_ManDfs( pNtk );
355 Vec_PtrForEachEntry( Nwk_Obj_t *, vObjs, pObj, i )
356 {
357 tArrival = Nwk_NodeComputeArrival( pObj, fUseSorting );
358 if ( Nwk_ObjIsCi(pObj) && pNtk->pManTime )
359 tArrival = Tim_ManGetCiArrival( pNtk->pManTime, pObj->PioId );
360 if ( Nwk_ObjIsCo(pObj) && pNtk->pManTime )
361 Tim_ManSetCoArrival( pNtk->pManTime, pObj->PioId, tArrival );
362 Nwk_ObjSetArrival( pObj, tArrival );
363 }
364 Vec_PtrFree( vObjs );
365
366 // get the latest arrival times
367 tArrival = -TIM_ETERNITY;
368 Nwk_ManForEachPo( pNtk, pObj, i )
369 if ( tArrival < Nwk_ObjArrival(pObj) )
370 tArrival = Nwk_ObjArrival(pObj);
371
372 // initialize the required times
373 if ( pNtk->pManTime )
374 {
376 Tim_ManInitPoRequiredAll( pNtk->pManTime, tArrival );
377 }
378 else
379 {
380 Nwk_ManForEachCo( pNtk, pObj, i )
381 Nwk_ObjSetRequired( pObj, tArrival );
382 }
383
384 // propagate the required times
385 Vec_PtrForEachEntry( Nwk_Obj_t *, vNodes, pObj, i )
386 {
387 if ( Nwk_ObjIsNode(pObj) )
388 {
389 Nwk_NodePropagateRequired( pObj, fUseSorting );
390 }
391 else if ( Nwk_ObjIsCi(pObj) )
392 {
393 if ( pNtk->pManTime )
394 Tim_ManSetCiRequired( pNtk->pManTime, pObj->PioId, Nwk_ObjRequired(pObj) );
395 }
396 else if ( Nwk_ObjIsCo(pObj) )
397 {
398 if ( pNtk->pManTime )
399 {
400 tRequired = Tim_ManGetCoRequired( pNtk->pManTime, pObj->PioId );
401 Nwk_ObjSetRequired( pObj, tRequired );
402 }
403 if ( Nwk_ObjRequired(Nwk_ObjFanin0(pObj)) > Nwk_ObjRequired(pObj) )
404 Nwk_ObjSetRequired( Nwk_ObjFanin0(pObj), Nwk_ObjRequired(pObj) );
405 }
406
407 // set slack for this object
408 tSlack = Nwk_ObjRequired(pObj) - Nwk_ObjArrival(pObj);
409 assert( tSlack + 0.01 > 0.0 );
410 Nwk_ObjSetSlack( pObj, tSlack < 0.0 ? 0.0 : tSlack );
411 }
412 Vec_PtrFree( vNodes );
413 return tArrival;
414}
struct If_LibLut_t_ If_LibLut_t
Definition if.h:82
ABC_NAMESPACE_IMPL_START void Nwk_ManCleanTiming(Nwk_Man_t *pNtk)
DECLARATIONS ///.
Definition nwkTiming.c:45
float Nwk_NodePropagateRequired(Nwk_Obj_t *pObj, int fUseSorting)
Definition nwkTiming.c:264
float Nwk_NodeComputeArrival(Nwk_Obj_t *pObj, int fUseSorting)
Definition nwkTiming.c:131
#define Nwk_ManForEachPo(p, pObj, i)
Definition nwk.h:186
ABC_DLL Vec_Ptr_t * Nwk_ManDfsReverse(Nwk_Man_t *pNtk)
Definition nwkDfs.c:451
#define Nwk_ManForEachCo(p, pObj, i)
Definition nwk.h:181
ABC_DLL Vec_Ptr_t * Nwk_ManDfs(Nwk_Man_t *pNtk)
Definition nwkDfs.c:321
ABC_DLL int Nwk_ManGetFaninMax(Nwk_Man_t *pNtk)
Definition nwkUtil.c:71
int LutMax
Definition if.h:190
Tim_Man_t * pManTime
Definition nwk.h:74
If_LibLut_t * pLutLib
Definition nwk.h:75
void Tim_ManSetCoArrival(Tim_Man_t *p, int iCo, float Delay)
Definition timTime.c:116
void Tim_ManIncrementTravId(Tim_Man_t *p)
DECLARATIONS ///.
Definition timTrav.c:44
void Tim_ManSetCiRequired(Tim_Man_t *p, int iCi, float Delay)
Definition timTime.c:135
void Tim_ManInitPoRequiredAll(Tim_Man_t *p, float Delay)
Definition timTime.c:97
float Tim_ManGetCiArrival(Tim_Man_t *p, int iCi)
Definition timTime.c:174
float Tim_ManGetCoRequired(Tim_Man_t *p, int iCo)
Definition timTime.c:222
#define assert(ex)
Definition util_old.h:213
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Nwk_ManDelayTracePrint()

void Nwk_ManDelayTracePrint ( Nwk_Man_t * pNtk)

Function*************************************************************

Synopsis [Prints the delay trace for the given network.]

Description []

SideEffects []

SeeAlso []

Definition at line 459 of file nwkTiming.c.

460{
461 If_LibLut_t * pLutLib = pNtk->pLutLib;
462 Nwk_Obj_t * pNode;
463 int i, Nodes, * pCounters;
464 float tArrival, tDelta, nSteps, Num;
465 // get the library
466 if ( pLutLib && pLutLib->LutMax < Nwk_ManGetFaninMax(pNtk) )
467 {
468 printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
469 pLutLib->LutMax, Nwk_ManGetFaninMax(pNtk) );
470 return;
471 }
472 // decide how many steps
473 nSteps = pLutLib ? 20 : Nwk_ManLevelMax(pNtk);
474 pCounters = ABC_ALLOC( int, nSteps + 1 );
475 memset( pCounters, 0, sizeof(int)*(nSteps + 1) );
476 // perform delay trace
477 tArrival = Nwk_ManDelayTraceLut( pNtk );
478 tDelta = tArrival / nSteps;
479 // count how many nodes have slack in the corresponding intervals
480 Nwk_ManForEachNode( pNtk, pNode, i )
481 {
482 if ( Nwk_ObjFaninNum(pNode) == 0 )
483 continue;
484 Num = Nwk_ObjSlack(pNode) / tDelta;
485 if ( Num > nSteps )
486 continue;
487 assert( Num >=0 && Num <= nSteps );
488 pCounters[(int)Num]++;
489 }
490 // print the results
491 printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pLutLib? "LUT library" : "unit-delay" );
492 Nodes = 0;
493 for ( i = 0; i < nSteps; i++ )
494 {
495 Nodes += pCounters[i];
496 printf( "%3d %s : %5d (%6.2f %%)\n", pLutLib? 5*(i+1) : i+1,
497 pLutLib? "%":"lev", Nodes, 100.0*Nodes/Nwk_ManNodeNum(pNtk) );
498 }
499 ABC_FREE( pCounters );
500}
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_FREE(obj)
Definition abc_global.h:267
float Nwk_ManDelayTraceLut(Nwk_Man_t *pNtk)
Definition nwkTiming.c:326
#define Nwk_ManForEachNode(p, pObj, i)
Definition nwk.h:192
ABC_DLL int Nwk_ManLevelMax(Nwk_Man_t *pNtk)
Definition nwkDfs.c:248
char * memset()
Here is the call graph for this function:

◆ Nwk_ManDelayTraceSortPins()

void Nwk_ManDelayTraceSortPins ( Nwk_Obj_t * pNode,
int * pPinPerm,
float * pPinDelays )

Function*************************************************************

Synopsis [Sorts the pins in the decreasing order of delays.]

Description []

SideEffects []

SeeAlso []

Definition at line 67 of file nwkTiming.c.

68{
69 Nwk_Obj_t * pFanin;
70 int i, j, best_i, temp;
71 // start the trivial permutation and collect pin delays
72 Nwk_ObjForEachFanin( pNode, pFanin, i )
73 {
74 pPinPerm[i] = i;
75 pPinDelays[i] = Nwk_ObjArrival(pFanin);
76 }
77 // selection sort the pins in the decreasible order of delays
78 // this order will match the increasing order of LUT input pins
79 for ( i = 0; i < Nwk_ObjFaninNum(pNode)-1; i++ )
80 {
81 best_i = i;
82 for ( j = i+1; j < Nwk_ObjFaninNum(pNode); j++ )
83 if ( pPinDelays[pPinPerm[j]] > pPinDelays[pPinPerm[best_i]] )
84 best_i = j;
85 if ( best_i == i )
86 continue;
87 temp = pPinPerm[i];
88 pPinPerm[i] = pPinPerm[best_i];
89 pPinPerm[best_i] = temp;
90 }
91 // verify
92 assert( Nwk_ObjFaninNum(pNode) == 0 || pPinPerm[0] < Nwk_ObjFaninNum(pNode) );
93 for ( i = 1; i < Nwk_ObjFaninNum(pNode); i++ )
94 {
95 assert( pPinPerm[i] < Nwk_ObjFaninNum(pNode) );
96 assert( pPinDelays[pPinPerm[i-1]] >= pPinDelays[pPinPerm[i]] );
97 }
98}
#define Nwk_ObjForEachFanin(pObj, pFanin, i)
Definition nwk.h:199
Here is the caller graph for this function:

◆ Nwk_ManUpdate()

void Nwk_ManUpdate ( Nwk_Obj_t * pObj,
Nwk_Obj_t * pObjNew,
Vec_Vec_t * vLevels )

Function*************************************************************

Synopsis [Replaces the node and incrementally updates levels.]

Description []

SideEffects []

SeeAlso []

Definition at line 860 of file nwkTiming.c.

861{
862 assert( pObj->pMan == pObjNew->pMan );
863 assert( pObj != pObjNew );
864 assert( Nwk_ObjFanoutNum(pObj) > 0 );
865 assert( Nwk_ObjIsNode(pObj) && !Nwk_ObjIsCo(pObjNew) );
866 // transfer fanouts to the old node
867 Nwk_ObjTransferFanout( pObj, pObjNew );
868 // transfer the timing information
869 // (this is needed because updating level happens if the level has changed;
870 // when we set the old level, it will be recomputed by the level updating
871 // procedure, which will update level of other nodes if there is a difference)
872 pObjNew->Level = pObj->Level;
873 pObjNew->tArrival = pObj->tArrival;
874 pObjNew->tRequired = pObj->tRequired;
875 // update required times of the old fanins
876 pObj->tRequired = TIM_ETERNITY;
878 // remove the old node
879 Nwk_ManDeleteNode_rec( pObj );
880 // update the information of the new node
881 Nwk_ManUpdateLevel( pObjNew );
882 Nwk_NodeUpdateArrival( pObjNew );
883 Nwk_NodeUpdateRequired( pObjNew );
884//Nwk_ManVerifyTiming( pObjNew->pMan );
885}
void Nwk_NodeUpdateArrival(Nwk_Obj_t *pObj)
Definition nwkTiming.c:562
void Nwk_NodeUpdateRequired(Nwk_Obj_t *pObj)
Definition nwkTiming.c:641
void Nwk_ManUpdateLevel(Nwk_Obj_t *pObj)
Definition nwkTiming.c:766
ABC_DLL void Nwk_ObjTransferFanout(Nwk_Obj_t *pNodeFrom, Nwk_Obj_t *pNodeTo)
Definition nwkFanio.c:272
ABC_DLL void Nwk_ManDeleteNode_rec(Nwk_Obj_t *pObj)
Definition nwkObj.c:183
Here is the call graph for this function:

◆ Nwk_ManUpdateLevel()

void Nwk_ManUpdateLevel ( Nwk_Obj_t * pObj)

Function*************************************************************

Synopsis [Incrementally updates level of the nodes.]

Description []

SideEffects []

SeeAlso []

Definition at line 766 of file nwkTiming.c.

767{
768 Tim_Man_t * pManTime = pObj->pMan->pManTime;
769 Vec_Ptr_t * vQueue = pObj->pMan->vTemp;
770 Nwk_Obj_t * pTemp;
771 Nwk_Obj_t * pNext = NULL; // Suppress "might be used uninitialized"
772 int LevelNew, iCur, k, iBox, iTerm1, nTerms;
773 assert( Nwk_ObjIsNode(pObj) );
774 // initialize the queue with the node
775 Vec_PtrClear( vQueue );
776 Vec_PtrPush( vQueue, pObj );
777 pObj->MarkA = 1;
778 // process objects
779 Vec_PtrForEachEntry( Nwk_Obj_t *, vQueue, pTemp, iCur )
780 {
781 pTemp->MarkA = 0;
782 LevelNew = Nwk_ObjLevelNew( pTemp );
783 if ( LevelNew == Nwk_ObjLevel(pTemp) )
784 continue;
785 Nwk_ObjSetLevel( pTemp, LevelNew );
786 // add the fanouts to the queue
787 if ( Nwk_ObjIsCo(pTemp) )
788 {
789 if ( pManTime )
790 {
791 iBox = Tim_ManBoxForCo( pManTime, pTemp->PioId );
792 if ( iBox >= 0 ) // this is not a true PO
793 {
794 Tim_ManSetCurrentTravIdBoxInputs( pManTime, iBox );
795 iTerm1 = Tim_ManBoxOutputFirst( pManTime, iBox );
796 nTerms = Tim_ManBoxOutputNum( pManTime, iBox );
797 for ( k = 0; k < nTerms; k++ )
798 {
799 pNext = Nwk_ManCi(pNext->pMan, iTerm1 + k);
800 if ( pNext->MarkA )
801 continue;
802 Nwk_NodeUpdateAddToQueue( vQueue, pNext, iCur, 1 );
803 pNext->MarkA = 1;
804 }
805 }
806 }
807 }
808 else
809 {
810 Nwk_ObjForEachFanout( pTemp, pNext, k )
811 {
812 if ( pNext->MarkA )
813 continue;
814 Nwk_NodeUpdateAddToQueue( vQueue, pNext, iCur, 1 );
815 pNext->MarkA = 1;
816 }
817 }
818 }
819}
void Nwk_NodeUpdateAddToQueue(Vec_Ptr_t *vQueue, Nwk_Obj_t *pObj, int iCurrent, int fArrival)
Definition nwkTiming.c:517
int Nwk_ObjLevelNew(Nwk_Obj_t *pObj)
Definition nwkTiming.c:725
#define Nwk_ObjForEachFanout(pObj, pFanout, i)
Definition nwk.h:201
int Tim_ManBoxOutputNum(Tim_Man_t *p, int iBox)
Definition timBox.c:203
typedefABC_NAMESPACE_HEADER_START struct Tim_Man_t_ Tim_Man_t
INCLUDES ///.
Definition tim.h:92
int Tim_ManBoxForCo(Tim_Man_t *p, int iCi)
Definition timBox.c:105
void Tim_ManSetCurrentTravIdBoxInputs(Tim_Man_t *p, int iBox)
Definition timTrav.c:70
int Tim_ManBoxOutputFirst(Tim_Man_t *p, int iBox)
Definition timBox.c:155
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Nwk_ManVerifyLevel()

int Nwk_ManVerifyLevel ( Nwk_Man_t * pNtk)

Function*************************************************************

Synopsis [Computes the level of the node using its fanin levels.]

Description []

SideEffects []

SeeAlso []

Definition at line 832 of file nwkTiming.c.

833{
834 Nwk_Obj_t * pObj;
835 int LevelNew, i;
836 Nwk_ManForEachObj( pNtk, pObj, i )
837 {
838 assert( pObj->MarkA == 0 );
839 LevelNew = Nwk_ObjLevelNew( pObj );
840 if ( Nwk_ObjLevel(pObj) != LevelNew )
841 {
842 printf( "Object %6d: Mismatch betweeh levels: Actual = %d. Correct = %d.\n",
843 i, Nwk_ObjLevel(pObj), LevelNew );
844 }
845 }
846 return 1;
847}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Nwk_ManVerifyTiming()

int Nwk_ManVerifyTiming ( Nwk_Man_t * pNtk)

Function*************************************************************

Synopsis [Computes the arrival times for the given node.]

Description []

SideEffects []

SeeAlso []

Definition at line 427 of file nwkTiming.c.

428{
429 Nwk_Obj_t * pObj;
430 float tArrival, tRequired;
431 int i;
432 Nwk_ManForEachObj( pNtk, pObj, i )
433 {
434 if ( Nwk_ObjIsCi(pObj) && Nwk_ObjFanoutNum(pObj) == 0 )
435 continue;
436 tArrival = Nwk_NodeComputeArrival( pObj, 1 );
437 tRequired = Nwk_NodeComputeRequired( pObj, 1 );
438 if ( !Nwk_ManTimeEqual( tArrival, Nwk_ObjArrival(pObj), (float)0.01 ) )
439 printf( "Nwk_ManVerifyTiming(): Object %d has different arrival time (%.2f) from computed (%.2f).\n",
440 pObj->Id, Nwk_ObjArrival(pObj), tArrival );
441 if ( !Nwk_ManTimeEqual( tRequired, Nwk_ObjRequired(pObj), (float)0.01 ) )
442 printf( "Nwk_ManVerifyTiming(): Object %d has different required time (%.2f) from computed (%.2f).\n",
443 pObj->Id, Nwk_ObjRequired(pObj), tRequired );
444 }
445 return 1;
446}
float Nwk_NodeComputeRequired(Nwk_Obj_t *pObj, int fUseSorting)
Definition nwkTiming.c:191
Here is the call graph for this function:

◆ Nwk_ManWhereIsPin()

int Nwk_ManWhereIsPin ( Nwk_Obj_t * pFanout,
Nwk_Obj_t * pFanin,
int * pPinPerm )

Function*************************************************************

Synopsis [Sorts the pins in the decreasing order of delays.]

Description []

SideEffects []

SeeAlso []

Definition at line 111 of file nwkTiming.c.

112{
113 int i;
114 for ( i = 0; i < Nwk_ObjFaninNum(pFanout); i++ )
115 if ( Nwk_ObjFanin(pFanout, pPinPerm[i]) == pFanin )
116 return i;
117 return -1;
118}
Here is the caller graph for this function:

◆ Nwk_NodeComputeArrival()

float Nwk_NodeComputeArrival ( Nwk_Obj_t * pObj,
int fUseSorting )

Function*************************************************************

Synopsis [Computes the arrival times for the given object.]

Description []

SideEffects []

SeeAlso []

Definition at line 131 of file nwkTiming.c.

132{
133 If_LibLut_t * pLutLib = pObj->pMan->pLutLib;
134 int pPinPerm[32];
135 float pPinDelays[32];
136 Nwk_Obj_t * pFanin;
137 float tArrival, * pDelays;
138 int k;
139 assert( Nwk_ObjIsNode(pObj) || Nwk_ObjIsCi(pObj) || Nwk_ObjIsCo(pObj) );
140 if ( Nwk_ObjIsCi(pObj) )
141 return Nwk_ObjArrival(pObj);
142 if ( Nwk_ObjIsCo(pObj) )
143 return Nwk_ObjArrival( Nwk_ObjFanin0(pObj) );
144 tArrival = -TIM_ETERNITY;
145 if ( pLutLib == NULL )
146 {
147 Nwk_ObjForEachFanin( pObj, pFanin, k )
148 if ( tArrival < Nwk_ObjArrival(pFanin) + 1.0 )
149 tArrival = Nwk_ObjArrival(pFanin) + 1.0;
150 }
151 else if ( !pLutLib->fVarPinDelays )
152 {
153 pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pObj)];
154 Nwk_ObjForEachFanin( pObj, pFanin, k )
155 if ( tArrival < Nwk_ObjArrival(pFanin) + pDelays[0] )
156 tArrival = Nwk_ObjArrival(pFanin) + pDelays[0];
157 }
158 else
159 {
160 pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pObj)];
161 if ( fUseSorting )
162 {
163 Nwk_ManDelayTraceSortPins( pObj, pPinPerm, pPinDelays );
164 Nwk_ObjForEachFanin( pObj, pFanin, k )
165 if ( tArrival < Nwk_ObjArrival(Nwk_ObjFanin(pObj,pPinPerm[k])) + pDelays[k] )
166 tArrival = Nwk_ObjArrival(Nwk_ObjFanin(pObj,pPinPerm[k])) + pDelays[k];
167 }
168 else
169 {
170 Nwk_ObjForEachFanin( pObj, pFanin, k )
171 if ( tArrival < Nwk_ObjArrival(pFanin) + pDelays[k] )
172 tArrival = Nwk_ObjArrival(pFanin) + pDelays[k];
173 }
174 }
175 if ( Nwk_ObjFaninNum(pObj) == 0 )
176 tArrival = 0.0;
177 return tArrival;
178}
void Nwk_ManDelayTraceSortPins(Nwk_Obj_t *pNode, int *pPinPerm, float *pPinDelays)
Definition nwkTiming.c:67
int fVarPinDelays
Definition if.h:191
float pLutDelays[IF_MAX_LUTSIZE+1][IF_MAX_LUTSIZE+1]
Definition if.h:193
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Nwk_NodeComputeRequired()

float Nwk_NodeComputeRequired ( Nwk_Obj_t * pObj,
int fUseSorting )

Function*************************************************************

Synopsis [Computes the required times for the given node.]

Description []

SideEffects []

SeeAlso []

Definition at line 191 of file nwkTiming.c.

192{
193 If_LibLut_t * pLutLib = pObj->pMan->pLutLib;
194 int pPinPerm[32];
195 float pPinDelays[32];
196 Nwk_Obj_t * pFanout;
197 float tRequired, tDelay, * pDelays;
198 int k, iFanin;
199 assert( Nwk_ObjIsNode(pObj) || Nwk_ObjIsCi(pObj) || Nwk_ObjIsCo(pObj) );
200 if ( Nwk_ObjIsCo(pObj) )
201 return Nwk_ObjRequired(pObj);
202 tRequired = TIM_ETERNITY;
203 if ( pLutLib == NULL )
204 {
205 Nwk_ObjForEachFanout( pObj, pFanout, k )
206 {
207 tDelay = Nwk_ObjIsCo(pFanout)? 0.0 : 1.0;
208 if ( tRequired > Nwk_ObjRequired(pFanout) - tDelay )
209 tRequired = Nwk_ObjRequired(pFanout) - tDelay;
210 }
211 }
212 else if ( !pLutLib->fVarPinDelays )
213 {
214 Nwk_ObjForEachFanout( pObj, pFanout, k )
215 {
216 pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pFanout)];
217 tDelay = Nwk_ObjIsCo(pFanout)? 0.0 : pDelays[0];
218 if ( tRequired > Nwk_ObjRequired(pFanout) - tDelay )
219 tRequired = Nwk_ObjRequired(pFanout) - tDelay;
220 }
221 }
222 else
223 {
224 if ( fUseSorting )
225 {
226 Nwk_ObjForEachFanout( pObj, pFanout, k )
227 {
228 pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pFanout)];
229 Nwk_ManDelayTraceSortPins( pFanout, pPinPerm, pPinDelays );
230 iFanin = Nwk_ManWhereIsPin( pFanout, pObj, pPinPerm );
231 assert( Nwk_ObjFanin(pFanout,pPinPerm[iFanin]) == pObj );
232 tDelay = Nwk_ObjIsCo(pFanout)? 0.0 : pDelays[iFanin];
233 if ( tRequired > Nwk_ObjRequired(pFanout) - tDelay )
234 tRequired = Nwk_ObjRequired(pFanout) - tDelay;
235 }
236 }
237 else
238 {
239 Nwk_ObjForEachFanout( pObj, pFanout, k )
240 {
241 pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pFanout)];
242 iFanin = Nwk_ObjFindFanin( pFanout, pObj );
243 assert( Nwk_ObjFanin(pFanout,iFanin) == pObj );
244 tDelay = Nwk_ObjIsCo(pFanout)? 0.0 : pDelays[iFanin];
245 if ( tRequired > Nwk_ObjRequired(pFanout) - tDelay )
246 tRequired = Nwk_ObjRequired(pFanout) - tDelay;
247 }
248 }
249 }
250 return tRequired;
251}
int Nwk_ManWhereIsPin(Nwk_Obj_t *pFanout, Nwk_Obj_t *pFanin, int *pPinPerm)
Definition nwkTiming.c:111
ABC_DLL int Nwk_ObjFindFanin(Nwk_Obj_t *pObj, Nwk_Obj_t *pFanin)
Definition nwkFanio.c:85
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Nwk_NodePropagateRequired()

float Nwk_NodePropagateRequired ( Nwk_Obj_t * pObj,
int fUseSorting )

Function*************************************************************

Synopsis [Propagates the required times through the given node.]

Description []

SideEffects []

SeeAlso []

Definition at line 264 of file nwkTiming.c.

265{
266 If_LibLut_t * pLutLib = pObj->pMan->pLutLib;
267 int pPinPerm[32];
268 float pPinDelays[32];
269 Nwk_Obj_t * pFanin;
270 float tRequired = 0.0; // Suppress "might be used uninitialized"
271 float * pDelays;
272 int k;
273 assert( Nwk_ObjIsNode(pObj) );
274 if ( pLutLib == NULL )
275 {
276 tRequired = Nwk_ObjRequired(pObj) - (float)1.0;
277 Nwk_ObjForEachFanin( pObj, pFanin, k )
278 if ( Nwk_ObjRequired(pFanin) > tRequired )
279 Nwk_ObjSetRequired( pFanin, tRequired );
280 }
281 else if ( !pLutLib->fVarPinDelays )
282 {
283 pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pObj)];
284 tRequired = Nwk_ObjRequired(pObj) - pDelays[0];
285 Nwk_ObjForEachFanin( pObj, pFanin, k )
286 if ( Nwk_ObjRequired(pFanin) > tRequired )
287 Nwk_ObjSetRequired( pFanin, tRequired );
288 }
289 else
290 {
291 pDelays = pLutLib->pLutDelays[Nwk_ObjFaninNum(pObj)];
292 if ( fUseSorting )
293 {
294 Nwk_ManDelayTraceSortPins( pObj, pPinPerm, pPinDelays );
295 Nwk_ObjForEachFanin( pObj, pFanin, k )
296 {
297 tRequired = Nwk_ObjRequired(pObj) - pDelays[k];
298 if ( Nwk_ObjRequired(Nwk_ObjFanin(pObj,pPinPerm[k])) > tRequired )
299 Nwk_ObjSetRequired( Nwk_ObjFanin(pObj,pPinPerm[k]), tRequired );
300 }
301 }
302 else
303 {
304 Nwk_ObjForEachFanin( pObj, pFanin, k )
305 {
306 tRequired = Nwk_ObjRequired(pObj) - pDelays[k];
307 if ( Nwk_ObjRequired(pFanin) > tRequired )
308 Nwk_ObjSetRequired( pFanin, tRequired );
309 }
310 }
311 }
312 return tRequired;
313}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Nwk_NodeUpdateAddToQueue()

void Nwk_NodeUpdateAddToQueue ( Vec_Ptr_t * vQueue,
Nwk_Obj_t * pObj,
int iCurrent,
int fArrival )

Function*************************************************************

Synopsis [Inserts node into the queue of nodes sorted by level.]

Description [The inserted node should not go before the current position given by iCurrent. If the arrival times are computed, the nodes are sorted in the increasing order of levels. If the required times are computed, the nodes are sorted in the decreasing order of levels.]

SideEffects []

SeeAlso []

Definition at line 517 of file nwkTiming.c.

518{
519 Nwk_Obj_t * pTemp1, * pTemp2;
520 int i;
521 Vec_PtrPush( vQueue, pObj );
522 for ( i = Vec_PtrSize(vQueue) - 1; i > iCurrent + 1; i-- )
523 {
524 pTemp1 = (Nwk_Obj_t *)vQueue->pArray[i];
525 pTemp2 = (Nwk_Obj_t *)vQueue->pArray[i-1];
526 if ( fArrival )
527 {
528 if ( Nwk_ObjLevel(pTemp2) <= Nwk_ObjLevel(pTemp1) )
529 break;
530 }
531 else
532 {
533 if ( Nwk_ObjLevel(pTemp2) >= Nwk_ObjLevel(pTemp1) )
534 break;
535 }
536 vQueue->pArray[i-1] = pTemp1;
537 vQueue->pArray[i] = pTemp2;
538 }
539 // verification
540 for ( i = iCurrent + 1; i < Vec_PtrSize(vQueue) - 1; i++ )
541 {
542 pTemp1 = (Nwk_Obj_t *)vQueue->pArray[i];
543 pTemp2 = (Nwk_Obj_t *)vQueue->pArray[i+1];
544 if ( fArrival )
545 assert( Nwk_ObjLevel(pTemp1) <= Nwk_ObjLevel(pTemp2) );
546 else
547 assert( Nwk_ObjLevel(pTemp1) >= Nwk_ObjLevel(pTemp2) );
548 }
549}
Here is the caller graph for this function:

◆ Nwk_NodeUpdateArrival()

void Nwk_NodeUpdateArrival ( Nwk_Obj_t * pObj)

Function*************************************************************

Synopsis [Incrementally updates arrival times of the node.]

Description [Supports variable-pin delay model and white-boxes.]

SideEffects []

SeeAlso []

Definition at line 562 of file nwkTiming.c.

563{
564 Tim_Man_t * pManTime = pObj->pMan->pManTime;
565 Vec_Ptr_t * vQueue = pObj->pMan->vTemp;
566 Nwk_Obj_t * pTemp;
567 Nwk_Obj_t * pNext = NULL; // Suppress "might be used uninitialized"
568 float tArrival;
569 int iCur, k, iBox, iTerm1, nTerms;
570 assert( Nwk_ObjIsNode(pObj) );
571 // verify the arrival time
572 tArrival = Nwk_NodeComputeArrival( pObj, 1 );
573 assert( Nwk_ManTimeLess( tArrival, Nwk_ObjRequired(pObj), (float)0.01 ) );
574 // initialize the queue with the node
575 Vec_PtrClear( vQueue );
576 Vec_PtrPush( vQueue, pObj );
577 pObj->MarkA = 1;
578 // process objects
579 if ( pManTime )
580 Tim_ManIncrementTravId( pManTime );
581 Vec_PtrForEachEntry( Nwk_Obj_t *, vQueue, pTemp, iCur )
582 {
583 pTemp->MarkA = 0;
584 tArrival = Nwk_NodeComputeArrival( pTemp, 1 );
585 if ( Nwk_ObjIsCi(pTemp) && pManTime )
586 tArrival = Tim_ManGetCiArrival( pManTime, pTemp->PioId );
587 if ( Nwk_ManTimeEqual( tArrival, Nwk_ObjArrival(pTemp), (float)0.01 ) )
588 continue;
589 Nwk_ObjSetArrival( pTemp, tArrival );
590 // add the fanouts to the queue
591 if ( Nwk_ObjIsCo(pTemp) )
592 {
593 if ( pManTime )
594 {
595 iBox = Tim_ManBoxForCo( pManTime, pTemp->PioId );
596 if ( iBox >= 0 ) // this CO is an input of the box
597 {
598 // it may happen that a box-input (CO) was already marked as visited
599 // when some other box-input of the same box was visited - here we undo this
600 if ( Tim_ManIsCoTravIdCurrent( pManTime, pTemp->PioId ) )
601 Tim_ManSetPreviousTravIdBoxInputs( pManTime, iBox );
602 Tim_ManSetCoArrival( pManTime, pTemp->PioId, tArrival );
603 Tim_ManSetCurrentTravIdBoxInputs( pManTime, iBox );
604 iTerm1 = Tim_ManBoxOutputFirst( pManTime, iBox );
605 nTerms = Tim_ManBoxOutputNum( pManTime, iBox );
606 for ( k = 0; k < nTerms; k++ )
607 {
608 pNext = Nwk_ManCi(pNext->pMan, iTerm1 + k);
609 if ( pNext->MarkA )
610 continue;
611 Nwk_NodeUpdateAddToQueue( vQueue, pNext, iCur, 1 );
612 pNext->MarkA = 1;
613 }
614 }
615 }
616 }
617 else
618 {
619 Nwk_ObjForEachFanout( pTemp, pNext, k )
620 {
621 if ( pNext->MarkA )
622 continue;
623 Nwk_NodeUpdateAddToQueue( vQueue, pNext, iCur, 1 );
624 pNext->MarkA = 1;
625 }
626 }
627 }
628}
void Tim_ManSetPreviousTravIdBoxInputs(Tim_Man_t *p, int iBox)
Definition timTrav.c:112
int Tim_ManIsCoTravIdCurrent(Tim_Man_t *p, int iCo)
Definition timTrav.c:172
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Nwk_NodeUpdateRequired()

void Nwk_NodeUpdateRequired ( Nwk_Obj_t * pObj)

Function*************************************************************

Synopsis [Incrementally updates required times of the node.]

Description [Supports variable-pin delay model and white-boxes.]

SideEffects []

SeeAlso []

Definition at line 641 of file nwkTiming.c.

642{
643 Tim_Man_t * pManTime = pObj->pMan->pManTime;
644 Vec_Ptr_t * vQueue = pObj->pMan->vTemp;
645 Nwk_Obj_t * pTemp;
646 Nwk_Obj_t * pNext = NULL; // Suppress "might be used uninitialized"
647 float tRequired;
648 int iCur, k, iBox, iTerm1, nTerms;
649 assert( Nwk_ObjIsNode(pObj) );
650 // make sure the node's required time remained the same
651 tRequired = Nwk_NodeComputeRequired( pObj, 1 );
652 assert( Nwk_ManTimeEqual( tRequired, Nwk_ObjRequired(pObj), (float)0.01 ) );
653 // initialize the queue with the node's faninsa and the old node's fanins
654 Vec_PtrClear( vQueue );
655 Nwk_ObjForEachFanin( pObj, pNext, k )
656 {
657 if ( pNext->MarkA )
658 continue;
659 Nwk_NodeUpdateAddToQueue( vQueue, pNext, -1, 0 );
660 pNext->MarkA = 1;
661 }
662 // process objects
663 if ( pManTime )
664 Tim_ManIncrementTravId( pManTime );
665 Vec_PtrForEachEntry( Nwk_Obj_t *, vQueue, pTemp, iCur )
666 {
667 pTemp->MarkA = 0;
668 tRequired = Nwk_NodeComputeRequired( pTemp, 1 );
669 if ( Nwk_ObjIsCo(pTemp) && pManTime )
670 tRequired = Tim_ManGetCoRequired( pManTime, pTemp->PioId );
671 if ( Nwk_ManTimeEqual( tRequired, Nwk_ObjRequired(pTemp), (float)0.01 ) )
672 continue;
673 Nwk_ObjSetRequired( pTemp, tRequired );
674 // add the fanins to the queue
675 if ( Nwk_ObjIsCi(pTemp) )
676 {
677 if ( pManTime )
678 {
679 iBox = Tim_ManBoxForCi( pManTime, pTemp->PioId );
680 if ( iBox >= 0 ) // this CI is an output of the box
681 {
682 // it may happen that a box-output (CI) was already marked as visited
683 // when some other box-output of the same box was visited - here we undo this
684 if ( Tim_ManIsCiTravIdCurrent( pManTime, pTemp->PioId ) )
685 Tim_ManSetPreviousTravIdBoxOutputs( pManTime, iBox );
686 Tim_ManSetCiRequired( pManTime, pTemp->PioId, tRequired );
687 Tim_ManSetCurrentTravIdBoxOutputs( pManTime, iBox );
688 iTerm1 = Tim_ManBoxInputFirst( pManTime, iBox );
689 nTerms = Tim_ManBoxInputNum( pManTime, iBox );
690 for ( k = 0; k < nTerms; k++ )
691 {
692 pNext = Nwk_ManCo(pNext->pMan, iTerm1 + k);
693 if ( pNext->MarkA )
694 continue;
695 Nwk_NodeUpdateAddToQueue( vQueue, pNext, iCur, 0 );
696 pNext->MarkA = 1;
697 }
698 }
699 }
700 }
701 else
702 {
703 Nwk_ObjForEachFanin( pTemp, pNext, k )
704 {
705 if ( pNext->MarkA )
706 continue;
707 Nwk_NodeUpdateAddToQueue( vQueue, pNext, iCur, 0 );
708 pNext->MarkA = 1;
709 }
710 }
711 }
712}
int Tim_ManBoxForCi(Tim_Man_t *p, int iCo)
Definition timBox.c:87
int Tim_ManBoxInputFirst(Tim_Man_t *p, int iBox)
Definition timBox.c:123
void Tim_ManSetPreviousTravIdBoxOutputs(Tim_Man_t *p, int iBox)
Definition timTrav.c:133
int Tim_ManBoxInputNum(Tim_Man_t *p, int iBox)
Definition timBox.c:187
void Tim_ManSetCurrentTravIdBoxOutputs(Tim_Man_t *p, int iBox)
Definition timTrav.c:91
int Tim_ManIsCiTravIdCurrent(Tim_Man_t *p, int iCi)
Definition timTrav.c:154
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Nwk_ObjLevelNew()

int Nwk_ObjLevelNew ( Nwk_Obj_t * pObj)

Function*************************************************************

Synopsis [Computes the level of the node using its fanin levels.]

Description []

SideEffects []

SeeAlso []

Definition at line 725 of file nwkTiming.c.

726{
727 Tim_Man_t * pManTime = pObj->pMan->pManTime;
728 Nwk_Obj_t * pFanin;
729 int i, iBox, iTerm1, nTerms, Level = 0;
730 if ( Nwk_ObjIsCi(pObj) || Nwk_ObjIsLatch(pObj) )
731 {
732 if ( pManTime )
733 {
734 iBox = Tim_ManBoxForCi( pManTime, pObj->PioId );
735 if ( iBox >= 0 ) // this CI is an output of the box
736 {
737 iTerm1 = Tim_ManBoxInputFirst( pManTime, iBox );
738 nTerms = Tim_ManBoxInputNum( pManTime, iBox );
739 for ( i = 0; i < nTerms; i++ )
740 {
741 pFanin = Nwk_ManCo(pObj->pMan, iTerm1 + i);
742 Level = Abc_MaxInt( Level, Nwk_ObjLevel(pFanin) );
743 }
744 Level++;
745 }
746 }
747 return Level;
748 }
749 assert( Nwk_ObjIsNode(pObj) || Nwk_ObjIsCo(pObj) );
750 Nwk_ObjForEachFanin( pObj, pFanin, i )
751 Level = Abc_MaxInt( Level, Nwk_ObjLevel(pFanin) );
752 return Level + (Nwk_ObjIsNode(pObj) && Nwk_ObjFaninNum(pObj) > 0);
753}
Here is the call graph for this function:
Here is the caller graph for this function: