ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
nwkTiming.c
Go to the documentation of this file.
1
20
21#include "nwk.h"
22
24
25
29
33
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
67void 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
111int 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
131float 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
191float 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
264float 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
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}
415
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
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
517void 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
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
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
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
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
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
860void 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;
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
891
892
894
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
struct If_LibLut_t_ If_LibLut_t
Definition if.h:82
struct Nwk_Man_t_ Nwk_Man_t
Definition ntlnwk.h:41
void Nwk_NodeUpdateArrival(Nwk_Obj_t *pObj)
Definition nwkTiming.c:562
ABC_NAMESPACE_IMPL_START void Nwk_ManCleanTiming(Nwk_Man_t *pNtk)
DECLARATIONS ///.
Definition nwkTiming.c:45
void Nwk_NodeUpdateAddToQueue(Vec_Ptr_t *vQueue, Nwk_Obj_t *pObj, int iCurrent, int fArrival)
Definition nwkTiming.c:517
void Nwk_NodeUpdateRequired(Nwk_Obj_t *pObj)
Definition nwkTiming.c:641
int Nwk_ObjLevelNew(Nwk_Obj_t *pObj)
Definition nwkTiming.c:725
int Nwk_ManVerifyLevel(Nwk_Man_t *pNtk)
Definition nwkTiming.c:832
int Nwk_ManWhereIsPin(Nwk_Obj_t *pFanout, Nwk_Obj_t *pFanin, int *pPinPerm)
Definition nwkTiming.c:111
void Nwk_ManDelayTracePrint(Nwk_Man_t *pNtk)
Definition nwkTiming.c:459
float Nwk_ManDelayTraceLut(Nwk_Man_t *pNtk)
Definition nwkTiming.c:326
void Nwk_ManUpdate(Nwk_Obj_t *pObj, Nwk_Obj_t *pObjNew, Vec_Vec_t *vLevels)
Definition nwkTiming.c:860
void Nwk_ManDelayTraceSortPins(Nwk_Obj_t *pNode, int *pPinPerm, float *pPinDelays)
Definition nwkTiming.c:67
void Nwk_ManUpdateLevel(Nwk_Obj_t *pObj)
Definition nwkTiming.c:766
int Nwk_ManVerifyTiming(Nwk_Man_t *pNtk)
Definition nwkTiming.c:427
float Nwk_NodePropagateRequired(Nwk_Obj_t *pObj, int fUseSorting)
Definition nwkTiming.c:264
float Nwk_NodeComputeRequired(Nwk_Obj_t *pObj, int fUseSorting)
Definition nwkTiming.c:191
float Nwk_NodeComputeArrival(Nwk_Obj_t *pObj, int fUseSorting)
Definition nwkTiming.c:131
#define Nwk_ManForEachPo(p, pObj, i)
Definition nwk.h:186
#define Nwk_ManForEachNode(p, pObj, i)
Definition nwk.h:192
ABC_DLL void Nwk_ObjTransferFanout(Nwk_Obj_t *pNodeFrom, Nwk_Obj_t *pNodeTo)
Definition nwkFanio.c:272
typedefABC_NAMESPACE_HEADER_START struct Nwk_Obj_t_ Nwk_Obj_t
INCLUDES ///.
Definition nwk.h:49
ABC_DLL int Nwk_ManLevelMax(Nwk_Man_t *pNtk)
Definition nwkDfs.c:248
#define Nwk_ManForEachObj(p, pObj, i)
Definition nwk.h:189
#define Nwk_ObjForEachFanout(pObj, pFanout, i)
Definition nwk.h:201
ABC_DLL void Nwk_ManDeleteNode_rec(Nwk_Obj_t *pObj)
Definition nwkObj.c:183
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
#define Nwk_ObjForEachFanin(pObj, pFanin, i)
Definition nwk.h:199
ABC_DLL int Nwk_ManGetFaninMax(Nwk_Man_t *pNtk)
Definition nwkUtil.c:71
ABC_DLL int Nwk_ObjFindFanin(Nwk_Obj_t *pObj, Nwk_Obj_t *pFanin)
Definition nwkFanio.c:85
int fVarPinDelays
Definition if.h:191
int LutMax
Definition if.h:190
float pLutDelays[IF_MAX_LUTSIZE+1][IF_MAX_LUTSIZE+1]
Definition if.h:193
Tim_Man_t * pManTime
Definition nwk.h:74
If_LibLut_t * pLutLib
Definition nwk.h:75
int Tim_ManBoxOutputNum(Tim_Man_t *p, int iBox)
Definition timBox.c:203
void Tim_ManSetCoArrival(Tim_Man_t *p, int iCo, float Delay)
Definition timTime.c:116
void Tim_ManSetPreviousTravIdBoxInputs(Tim_Man_t *p, int iBox)
Definition timTrav.c:112
typedefABC_NAMESPACE_HEADER_START struct Tim_Man_t_ Tim_Man_t
INCLUDES ///.
Definition tim.h:92
void Tim_ManIncrementTravId(Tim_Man_t *p)
DECLARATIONS ///.
Definition timTrav.c:44
int Tim_ManBoxForCi(Tim_Man_t *p, int iCo)
Definition timBox.c:87
int Tim_ManBoxForCo(Tim_Man_t *p, int iCi)
Definition timBox.c:105
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
int Tim_ManIsCoTravIdCurrent(Tim_Man_t *p, int iCo)
Definition timTrav.c:172
void Tim_ManSetCiRequired(Tim_Man_t *p, int iCi, float Delay)
Definition timTime.c:135
void Tim_ManSetCurrentTravIdBoxInputs(Tim_Man_t *p, int iBox)
Definition timTrav.c:70
void Tim_ManInitPoRequiredAll(Tim_Man_t *p, float Delay)
Definition timTime.c:97
void Tim_ManSetCurrentTravIdBoxOutputs(Tim_Man_t *p, int iBox)
Definition timTrav.c:91
#define TIM_ETERNITY
MACRO DEFINITIONS ///.
Definition tim.h:98
int Tim_ManIsCiTravIdCurrent(Tim_Man_t *p, int iCi)
Definition timTrav.c:154
float Tim_ManGetCiArrival(Tim_Man_t *p, int iCi)
Definition timTime.c:174
int Tim_ManBoxOutputFirst(Tim_Man_t *p, int iBox)
Definition timBox.c:155
float Tim_ManGetCoRequired(Tim_Man_t *p, int iCo)
Definition timTime.c:222
#define assert(ex)
Definition util_old.h:213
char * memset()
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
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition vecVec.h:42