abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
nwkTiming.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [nwkTiming.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Logic network representation.]
8 
9  Synopsis [Manipulation of timing information.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: nwkTiming.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "nwk.h"
22 
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 /// DECLARATIONS ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 ////////////////////////////////////////////////////////////////////////
31 /// FUNCTION DEFINITIONS ///
32 ////////////////////////////////////////////////////////////////////////
33 
34 /**Function*************************************************************
35 
36  Synopsis [Cleans timing information for all nodes.]
37 
38  Description []
39 
40  SideEffects []
41 
42  SeeAlso []
43 
44 ***********************************************************************/
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 }
55 
56 /**Function*************************************************************
57 
58  Synopsis [Sorts the pins in the decreasing order of delays.]
59 
60  Description []
61 
62  SideEffects []
63 
64  SeeAlso []
65 
66 ***********************************************************************/
67 void Nwk_ManDelayTraceSortPins( Nwk_Obj_t * pNode, int * pPinPerm, float * pPinDelays )
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 }
99 
100 /**Function*************************************************************
101 
102  Synopsis [Sorts the pins in the decreasing order of delays.]
103 
104  Description []
105 
106  SideEffects []
107 
108  SeeAlso []
109 
110 ***********************************************************************/
111 int Nwk_ManWhereIsPin( Nwk_Obj_t * pFanout, Nwk_Obj_t * pFanin, int * pPinPerm )
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 }
119 
120 /**Function*************************************************************
121 
122  Synopsis [Computes the arrival times for the given object.]
123 
124  Description []
125 
126  SideEffects []
127 
128  SeeAlso []
129 
130 ***********************************************************************/
131 float Nwk_NodeComputeArrival( Nwk_Obj_t * pObj, int fUseSorting )
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 }
179 
180 /**Function*************************************************************
181 
182  Synopsis [Computes the required times for the given node.]
183 
184  Description []
185 
186  SideEffects []
187 
188  SeeAlso []
189 
190 ***********************************************************************/
191 float Nwk_NodeComputeRequired( Nwk_Obj_t * pObj, int fUseSorting )
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 }
252 
253 /**Function*************************************************************
254 
255  Synopsis [Propagates the required times through the given node.]
256 
257  Description []
258 
259  SideEffects []
260 
261  SeeAlso []
262 
263 ***********************************************************************/
264 float Nwk_NodePropagateRequired( Nwk_Obj_t * pObj, int fUseSorting )
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 }
314 
315 /**Function*************************************************************
316 
317  Synopsis [Computes the delay trace of the given network.]
318 
319  Description []
320 
321  SideEffects []
322 
323  SeeAlso []
324 
325 ***********************************************************************/
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) )
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 }
415 
416 /**Function*************************************************************
417 
418  Synopsis [Computes the arrival times for the given node.]
419 
420  Description []
421 
422  SideEffects []
423 
424  SeeAlso []
425 
426 ***********************************************************************/
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 }
447 
448 /**Function*************************************************************
449 
450  Synopsis [Prints the delay trace for the given network.]
451 
452  Description []
453 
454  SideEffects []
455 
456  SeeAlso []
457 
458 ***********************************************************************/
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 }
501 
502 
503 /**Function*************************************************************
504 
505  Synopsis [Inserts node into the queue of nodes sorted by level.]
506 
507  Description [The inserted node should not go before the current position
508  given by iCurrent. If the arrival times are computed, the nodes are sorted
509  in the increasing order of levels. If the required times are computed,
510  the nodes are sorted in the decreasing order of levels.]
511 
512  SideEffects []
513 
514  SeeAlso []
515 
516 ***********************************************************************/
517 void Nwk_NodeUpdateAddToQueue( Vec_Ptr_t * vQueue, Nwk_Obj_t * pObj, int iCurrent, int fArrival )
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 }
550 
551 /**Function*************************************************************
552 
553  Synopsis [Incrementally updates arrival times of the node.]
554 
555  Description [Supports variable-pin delay model and white-boxes.]
556 
557  SideEffects []
558 
559  SeeAlso []
560 
561 ***********************************************************************/
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 }
629 
630 /**Function*************************************************************
631 
632  Synopsis [Incrementally updates required times of the node.]
633 
634  Description [Supports variable-pin delay model and white-boxes.]
635 
636  SideEffects []
637 
638  SeeAlso []
639 
640 ***********************************************************************/
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 }
713 
714 /**Function*************************************************************
715 
716  Synopsis [Computes the level of the node using its fanin levels.]
717 
718  Description []
719 
720  SideEffects []
721 
722  SeeAlso []
723 
724 ***********************************************************************/
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 }
754 
755 /**Function*************************************************************
756 
757  Synopsis [Incrementally updates level of the nodes.]
758 
759  Description []
760 
761  SideEffects []
762 
763  SeeAlso []
764 
765 ***********************************************************************/
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 }
820 
821 /**Function*************************************************************
822 
823  Synopsis [Computes the level of the node using its fanin levels.]
824 
825  Description []
826 
827  SideEffects []
828 
829  SeeAlso []
830 
831 ***********************************************************************/
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 }
848 
849 /**Function*************************************************************
850 
851  Synopsis [Replaces the node and incrementally updates levels.]
852 
853  Description []
854 
855  SideEffects []
856 
857  SeeAlso []
858 
859 ***********************************************************************/
860 void Nwk_ManUpdate( Nwk_Obj_t * pObj, Nwk_Obj_t * pObjNew, Vec_Vec_t * vLevels )
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;
877  Nwk_NodeUpdateRequired( pObj );
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 }
886 
887 
888 ////////////////////////////////////////////////////////////////////////
889 /// END OF FILE ///
890 ////////////////////////////////////////////////////////////////////////
891 
892 
894 
char * memset()
int Tim_ManBoxOutputFirst(Tim_Man_t *p, int iBox)
Definition: timBox.c:154
int Tim_ManBoxForCi(Tim_Man_t *p, int iCo)
Definition: timBox.c:86
static Nwk_Obj_t * Nwk_ManCo(Nwk_Man_t *p, int i)
Definition: nwk.h:132
float Nwk_NodeComputeRequired(Nwk_Obj_t *pObj, int fUseSorting)
Definition: nwkTiming.c:191
int Tim_ManIsCiTravIdCurrent(Tim_Man_t *p, int iCi)
Definition: timTrav.c:154
static int Nwk_ObjIsCi(Nwk_Obj_t *p)
Definition: nwk.h:146
static Nwk_Obj_t * Nwk_ManCi(Nwk_Man_t *p, int i)
Definition: nwk.h:131
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
int Nwk_ObjLevelNew(Nwk_Obj_t *pObj)
Definition: nwkTiming.c:725
ABC_DLL void Nwk_ManDeleteNode_rec(Nwk_Obj_t *pObj)
Definition: nwkObj.c:183
static int Nwk_ObjFanoutNum(Nwk_Obj_t *p)
Definition: nwk.h:138
void Tim_ManSetCurrentTravIdBoxOutputs(Tim_Man_t *p, int iBox)
Definition: timTrav.c:91
#define Nwk_ManForEachCo(p, pObj, i)
Definition: nwk.h:181
void Tim_ManIncrementTravId(Tim_Man_t *p)
DECLARATIONS ///.
Definition: timTrav.c:44
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition: vecVec.h:42
ABC_DLL void Nwk_ObjTransferFanout(Nwk_Obj_t *pNodeFrom, Nwk_Obj_t *pNodeTo)
Definition: nwkFanio.c:272
static int Nwk_ManTimeLess(float f1, float f2, float Eps)
Definition: nwk.h:172
typedefABC_NAMESPACE_HEADER_START struct Nwk_Obj_t_ Nwk_Obj_t
INCLUDES ///.
Definition: nwk.h:49
static float Nwk_ObjSlack(Nwk_Obj_t *pObj)
Definition: nwk.h:157
ABC_DLL Vec_Ptr_t * Nwk_ManDfsReverse(Nwk_Man_t *pNtk)
Definition: nwkDfs.c:451
int Tim_ManBoxForCo(Tim_Man_t *p, int iCi)
Definition: timBox.c:104
static void Nwk_ObjSetSlack(Nwk_Obj_t *pObj, float Time)
Definition: nwk.h:160
void Tim_ManSetCoArrival(Tim_Man_t *p, int iCo, float Delay)
Definition: timTime.c:116
int LutMax
Definition: if.h:173
float Nwk_NodePropagateRequired(Nwk_Obj_t *pObj, int fUseSorting)
Definition: nwkTiming.c:264
#define Nwk_ObjForEachFanout(pObj, pFanout, i)
Definition: nwk.h:201
float pLutDelays[IF_MAX_LUTSIZE+1][IF_MAX_LUTSIZE+1]
Definition: if.h:176
static void Vec_PtrPush(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:606
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
void Tim_ManSetCurrentTravIdBoxInputs(Tim_Man_t *p, int iBox)
Definition: timTrav.c:70
int Tim_ManBoxOutputNum(Tim_Man_t *p, int iBox)
Definition: timBox.c:202
void Nwk_ManUpdateLevel(Nwk_Obj_t *pObj)
Definition: nwkTiming.c:766
float Nwk_NodeComputeArrival(Nwk_Obj_t *pObj, int fUseSorting)
Definition: nwkTiming.c:131
static int Abc_MaxInt(int a, int b)
Definition: abc_global.h:238
static int Vec_PtrSize(Vec_Ptr_t *p)
Definition: vecPtr.h:295
void Tim_ManSetPreviousTravIdBoxOutputs(Tim_Man_t *p, int iBox)
Definition: timTrav.c:133
ABC_DLL int Nwk_ManLevelMax(Nwk_Man_t *pNtk)
Definition: nwkDfs.c:248
static int Nwk_ObjFaninNum(Nwk_Obj_t *p)
Definition: nwk.h:137
ABC_DLL int Nwk_ObjFindFanin(Nwk_Obj_t *pObj, Nwk_Obj_t *pFanin)
Definition: nwkFanio.c:85
void Tim_ManSetPreviousTravIdBoxInputs(Tim_Man_t *p, int iBox)
Definition: timTrav.c:112
void Tim_ManSetCiRequired(Tim_Man_t *p, int iCi, float Delay)
Definition: timTime.c:135
ABC_NAMESPACE_IMPL_START void Nwk_ManCleanTiming(Nwk_Man_t *pNtk)
DECLARATIONS ///.
Definition: nwkTiming.c:45
static float Nwk_ObjArrival(Nwk_Obj_t *pObj)
Definition: nwk.h:155
int Tim_ManIsCoTravIdCurrent(Tim_Man_t *p, int iCo)
Definition: timTrav.c:172
ABC_DLL Vec_Ptr_t * Nwk_ManDfs(Nwk_Man_t *pNtk)
Definition: nwkDfs.c:321
void Nwk_ManDelayTracePrint(Nwk_Man_t *pNtk)
Definition: nwkTiming.c:459
int fVarPinDelays
Definition: if.h:174
static int Nwk_ObjIsCo(Nwk_Obj_t *p)
Definition: nwk.h:147
Definition: nwk.h:61
static int Nwk_ObjIsLatch(Nwk_Obj_t *p)
Definition: nwk.h:149
If_LibLut_t * pLutLib
Definition: nwk.h:75
void Nwk_ManDelayTraceSortPins(Nwk_Obj_t *pNode, int *pPinPerm, float *pPinDelays)
Definition: nwkTiming.c:67
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
int Nwk_ManVerifyLevel(Nwk_Man_t *pNtk)
Definition: nwkTiming.c:832
#define Nwk_ManForEachPo(p, pObj, i)
Definition: nwk.h:186
Tim_Man_t * pManTime
Definition: nwk.h:74
int Tim_ManBoxInputNum(Tim_Man_t *p, int iBox)
Definition: timBox.c:186
static int Nwk_ObjIsNode(Nwk_Obj_t *p)
Definition: nwk.h:148
ABC_DLL int Nwk_ManGetFaninMax(Nwk_Man_t *pNtk)
Definition: nwkUtil.c:71
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
static void Nwk_ObjSetArrival(Nwk_Obj_t *pObj, float Time)
Definition: nwk.h:158
static void Nwk_ObjSetLevel(Nwk_Obj_t *pObj, int Level)
Definition: nwk.h:163
static int Nwk_ManTimeEqual(float f1, float f2, float Eps)
Definition: nwk.h:171
static Nwk_Obj_t * Nwk_ObjFanin(Nwk_Obj_t *p, int i)
Definition: nwk.h:142
#define Nwk_ObjForEachFanin(pObj, pFanin, i)
Definition: nwk.h:199
void Nwk_NodeUpdateArrival(Nwk_Obj_t *pObj)
Definition: nwkTiming.c:562
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define TIM_ETERNITY
MACRO DEFINITIONS ///.
Definition: tim.h:98
void Nwk_ManUpdate(Nwk_Obj_t *pObj, Nwk_Obj_t *pObjNew, Vec_Vec_t *vLevels)
Definition: nwkTiming.c:860
void Nwk_NodeUpdateAddToQueue(Vec_Ptr_t *vQueue, Nwk_Obj_t *pObj, int iCurrent, int fArrival)
Definition: nwkTiming.c:517
#define Nwk_ManForEachObj(p, pObj, i)
Definition: nwk.h:189
void Nwk_NodeUpdateRequired(Nwk_Obj_t *pObj)
Definition: nwkTiming.c:641
static int Nwk_ManNodeNum(Nwk_Man_t *p)
Definition: nwk.h:127
static Nwk_Obj_t * Nwk_ObjFanin0(Nwk_Obj_t *p)
Definition: nwk.h:140
static int Nwk_ObjLevel(Nwk_Obj_t *pObj)
Definition: nwk.h:162
float Tim_ManGetCoRequired(Tim_Man_t *p, int iCo)
Definition: timTime.c:222
int Nwk_ManVerifyTiming(Nwk_Man_t *pNtk)
Definition: nwkTiming.c:427
#define assert(ex)
Definition: util_old.h:213
static void Vec_PtrClear(Vec_Ptr_t *p)
Definition: vecPtr.h:545
typedefABC_NAMESPACE_HEADER_START struct Tim_Man_t_ Tim_Man_t
INCLUDES ///.
Definition: tim.h:92
static float Nwk_ObjRequired(Nwk_Obj_t *pObj)
Definition: nwk.h:156
float Nwk_ManDelayTraceLut(Nwk_Man_t *pNtk)
Definition: nwkTiming.c:326
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition: vecPtr.h:55
int Tim_ManBoxInputFirst(Tim_Man_t *p, int iBox)
Definition: timBox.c:122
float Tim_ManGetCiArrival(Tim_Man_t *p, int iCi)
Definition: timTime.c:174
static void Nwk_ObjSetRequired(Nwk_Obj_t *pObj, float Time)
Definition: nwk.h:159
int Nwk_ManWhereIsPin(Nwk_Obj_t *pFanout, Nwk_Obj_t *pFanin, int *pPinPerm)
Definition: nwkTiming.c:111
void Tim_ManInitPoRequiredAll(Tim_Man_t *p, float Delay)
Definition: timTime.c:97
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223
#define Nwk_ManForEachNode(p, pObj, i)
Definition: nwk.h:192