1 /**CFile****************************************************************
2 
3   FileName    [timMan.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Hierarchy/timing manager.]
8 
9   Synopsis    [Manipulation of manager data-structure.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - April 28, 2007.]
16 
17   Revision    [$Id: timMan.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "timInt.h"
22 #include "map/if/if.h"
23 
24 ABC_NAMESPACE_IMPL_START
25 
26 ////////////////////////////////////////////////////////////////////////
27 ///                        DECLARATIONS                              ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 ////////////////////////////////////////////////////////////////////////
31 ///                     FUNCTION DEFINITIONS                         ///
32 ////////////////////////////////////////////////////////////////////////
33 
34 /**Function*************************************************************
35 
36   Synopsis    [Starts the timing manager.]
37 
38   Description []
39 
40   SideEffects []
41 
42   SeeAlso     []
43 
44 ***********************************************************************/
Tim_ManStart(int nCis,int nCos)45 Tim_Man_t * Tim_ManStart( int nCis, int nCos )
46 {
47     Tim_Man_t * p;
48     Tim_Obj_t * pObj;
49     int i;
50     p = ABC_ALLOC( Tim_Man_t, 1 );
51     memset( p, 0, sizeof(Tim_Man_t) );
52     p->pMemObj = Mem_FlexStart();
53     p->nCis = nCis;
54     p->nCos = nCos;
55     p->pCis = ABC_ALLOC( Tim_Obj_t, nCis );
56     memset( p->pCis, 0, sizeof(Tim_Obj_t) * nCis );
57     p->pCos = ABC_ALLOC( Tim_Obj_t, nCos );
58     memset( p->pCos, 0, sizeof(Tim_Obj_t) * nCos );
59     Tim_ManForEachCi( p, pObj, i )
60     {
61         pObj->Id = i;
62         pObj->iObj2Box = pObj->iObj2Num = -1;
63         pObj->timeReq = TIM_ETERNITY;
64     }
65     Tim_ManForEachCo( p, pObj, i )
66     {
67         pObj->Id = i;
68         pObj->iObj2Box = pObj->iObj2Num = -1;
69         pObj->timeReq = TIM_ETERNITY;
70     }
71     p->fUseTravId = 1;
72     return p;
73 }
74 
75 /**Function*************************************************************
76 
77   Synopsis    [Duplicates the timing manager.]
78 
79   Description []
80 
81   SideEffects []
82 
83   SeeAlso     []
84 
85 ***********************************************************************/
Tim_ManDup(Tim_Man_t * p,int fUnitDelay)86 Tim_Man_t * Tim_ManDup( Tim_Man_t * p, int fUnitDelay )
87 {
88     Tim_Man_t * pNew;
89     Tim_Box_t * pBox;
90     Tim_Obj_t * pObj;
91     float * pDelayTable, * pDelayTableNew;
92     int i, k, nInputs, nOutputs;
93     // clear traversal IDs
94     Tim_ManForEachCi( p, pObj, i )
95         pObj->TravId = 0;
96     Tim_ManForEachCo( p, pObj, i )
97         pObj->TravId = 0;
98     // create new manager
99     pNew = Tim_ManStart( p->nCis, p->nCos );
100     // copy box connectivity information
101     memcpy( pNew->pCis, p->pCis, sizeof(Tim_Obj_t) * p->nCis );
102     memcpy( pNew->pCos, p->pCos, sizeof(Tim_Obj_t) * p->nCos );
103     if ( fUnitDelay )
104     {
105         // discretize PI arrival times
106 //        Tim_ManForEachPi( pNew, pObj, k )
107 //          pObj->timeArr = (int)pObj->timeArr;
108         // discretize PO required times
109 //        Tim_ManForEachPo( pNew, pObj, k )
110 //          pObj->timeReq = 1 + (int)pObj->timeReq;
111         // clear PI arrival and PO required
112         Tim_ManInitPiArrivalAll( p, 0.0 );
113         Tim_ManInitPoRequiredAll( p, (float)TIM_ETERNITY );
114     }
115     // duplicate delay tables
116     if ( Tim_ManDelayTableNum(p) > 0 )
117     {
118         pNew->vDelayTables = Vec_PtrStart( Vec_PtrSize(p->vDelayTables) );
119         Tim_ManForEachTable( p, pDelayTable, i )
120         {
121             if ( pDelayTable == NULL )
122                 continue;
123             assert( i == (int)pDelayTable[0] );
124             nInputs   = (int)pDelayTable[1];
125             nOutputs  = (int)pDelayTable[2];
126             pDelayTableNew = ABC_ALLOC( float, 3 + nInputs * nOutputs );
127             pDelayTableNew[0] = (int)pDelayTable[0];
128             pDelayTableNew[1] = (int)pDelayTable[1];
129             pDelayTableNew[2] = (int)pDelayTable[2];
130             for ( k = 0; k < nInputs * nOutputs; k++ )
131                 if ( pDelayTable[3+k] == -ABC_INFINITY )
132                     pDelayTableNew[3+k] = -ABC_INFINITY;
133                 else
134                     pDelayTableNew[3+k] = fUnitDelay ? (float)fUnitDelay : pDelayTable[3+k];
135 //            assert( (int)pDelayTableNew[0] == Vec_PtrSize(pNew->vDelayTables) );
136             assert( Vec_PtrEntry(pNew->vDelayTables, i) == NULL );
137             Vec_PtrWriteEntry( pNew->vDelayTables, i, pDelayTableNew );
138 //printf( "Finished duplicating delay table %d.\n", i );
139         }
140     }
141     // duplicate boxes
142     if ( Tim_ManBoxNum(p) > 0 )
143     {
144         pNew->vBoxes = Vec_PtrAlloc( Tim_ManBoxNum(p) );
145         Tim_ManForEachBox( p, pBox, i )
146         {
147            Tim_ManCreateBox( pNew, pBox->Inouts[0], pBox->nInputs,
148                 pBox->Inouts[pBox->nInputs], pBox->nOutputs, pBox->iDelayTable, pBox->fBlack );
149            Tim_ManBoxSetCopy( pNew, i, pBox->iCopy );
150         }
151     }
152     return pNew;
153 }
154 
155 /**Function*************************************************************
156 
157   Synopsis    [Trims the timing manager.]
158 
159   Description []
160 
161   SideEffects []
162 
163   SeeAlso     []
164 
165 ***********************************************************************/
Tim_ManTrim(Tim_Man_t * p,Vec_Int_t * vBoxPres)166 Tim_Man_t * Tim_ManTrim( Tim_Man_t * p, Vec_Int_t * vBoxPres )
167 {
168     Tim_Man_t * pNew;
169     Tim_Box_t * pBox;
170     Tim_Obj_t * pObj;
171     float * pDelayTable, * pDelayTableNew;
172     int i, k, nNewCis, nNewCos, nInputs, nOutputs;
173     assert( Vec_IntSize(vBoxPres) == Tim_ManBoxNum(p) );
174     // count the number of CIs and COs in the trimmed manager
175     nNewCis = Tim_ManPiNum(p);
176     nNewCos = Tim_ManPoNum(p);
177     if ( Tim_ManBoxNum(p) )
178         Tim_ManForEachBox( p, pBox, i )
179             if ( Vec_IntEntry(vBoxPres, i) )
180             {
181                 nNewCis += pBox->nOutputs;
182                 nNewCos += pBox->nInputs;
183             }
184     if ( nNewCis == Tim_ManCiNum(p) && nNewCos == Tim_ManCoNum(p) )
185         return Tim_ManDup( p, 0 );
186     assert( nNewCis < Tim_ManCiNum(p) );
187     assert( nNewCos < Tim_ManCoNum(p) );
188     // clear traversal IDs
189     Tim_ManForEachCi( p, pObj, i )
190         pObj->TravId = 0;
191     Tim_ManForEachCo( p, pObj, i )
192         pObj->TravId = 0;
193     // create new manager
194     pNew = Tim_ManStart( nNewCis, nNewCos );
195     // copy box connectivity information
196     memcpy( pNew->pCis, p->pCis, sizeof(Tim_Obj_t) * Tim_ManPiNum(p) );
197     memcpy( pNew->pCos + nNewCos - Tim_ManPoNum(p),
198             p->pCos + Tim_ManCoNum(p) - Tim_ManPoNum(p),
199             sizeof(Tim_Obj_t) * Tim_ManPoNum(p) );
200     // duplicate delay tables
201     if ( Tim_ManDelayTableNum(p) > 0 )
202     {
203         pNew->vDelayTables = Vec_PtrStart( Vec_PtrSize(p->vDelayTables) );
204         Tim_ManForEachTable( p, pDelayTable, i )
205         {
206             if ( pDelayTable == NULL )
207                 continue;
208             assert( i == (int)pDelayTable[0] );
209             nInputs   = (int)pDelayTable[1];
210             nOutputs  = (int)pDelayTable[2];
211             pDelayTableNew = ABC_ALLOC( float, 3 + nInputs * nOutputs );
212             pDelayTableNew[0] = (int)pDelayTable[0];
213             pDelayTableNew[1] = (int)pDelayTable[1];
214             pDelayTableNew[2] = (int)pDelayTable[2];
215             for ( k = 0; k < nInputs * nOutputs; k++ )
216                 pDelayTableNew[3+k] = pDelayTable[3+k];
217 //            assert( (int)pDelayTableNew[0] == Vec_PtrSize(pNew->vDelayTables) );
218             assert( Vec_PtrEntry(pNew->vDelayTables, i) == NULL );
219             Vec_PtrWriteEntry( pNew->vDelayTables, i, pDelayTableNew );
220         }
221     }
222     // duplicate boxes
223     if ( Tim_ManBoxNum(p) > 0 )
224     {
225         int curPi = Tim_ManPiNum(p);
226         int curPo = 0;
227         pNew->vBoxes = Vec_PtrAlloc( Tim_ManBoxNum(p) );
228         Tim_ManForEachBox( p, pBox, i )
229             if ( Vec_IntEntry(vBoxPres, i) )
230             {
231                 Tim_ManCreateBox( pNew, curPo, pBox->nInputs, curPi, pBox->nOutputs, pBox->iDelayTable, pBox->fBlack );
232                 Tim_ManBoxSetCopy( pNew, Tim_ManBoxNum(pNew) - 1, Tim_ManBoxCopy(p, i) == -1 ? i : Tim_ManBoxCopy(p, i) );
233                 curPi += pBox->nOutputs;
234                 curPo += pBox->nInputs;
235             }
236         curPo += Tim_ManPoNum(p);
237         assert( curPi == Tim_ManCiNum(pNew) );
238         assert( curPo == Tim_ManCoNum(pNew) );
239     }
240     return pNew;
241 }
242 
243 /**Function*************************************************************
244 
245   Synopsis    [Reduces the timing manager.]
246 
247   Description []
248 
249   SideEffects []
250 
251   SeeAlso     []
252 
253 ***********************************************************************/
Tim_ManReduce(Tim_Man_t * p,Vec_Int_t * vBoxesLeft,int nTermsDiff)254 Tim_Man_t * Tim_ManReduce( Tim_Man_t * p, Vec_Int_t * vBoxesLeft, int nTermsDiff )
255 {
256     Tim_Man_t * pNew;
257     Tim_Box_t * pBox;
258     Tim_Obj_t * pObj;
259     float * pDelayTable, * pDelayTableNew;
260     int i, k, iBox, nNewCis, nNewCos, nInputs, nOutputs;
261     int nNewPiNum = Tim_ManPiNum(p) - nTermsDiff;
262     int nNewPoNum = Tim_ManPoNum(p) - nTermsDiff;
263     assert( Vec_IntSize(vBoxesLeft) <= Tim_ManBoxNum(p) );
264     // count the number of CIs and COs in the trimmed manager
265     nNewCis = nNewPiNum;
266     nNewCos = nNewPoNum;
267     Vec_IntForEachEntry( vBoxesLeft, iBox, i )
268     {
269         pBox = Tim_ManBox( p, iBox );
270         nNewCis += pBox->nOutputs;
271         nNewCos += pBox->nInputs;
272     }
273     assert( nNewCis <= Tim_ManCiNum(p) - nTermsDiff );
274     assert( nNewCos <= Tim_ManCoNum(p) - nTermsDiff );
275     // clear traversal IDs
276     Tim_ManForEachCi( p, pObj, i )
277         pObj->TravId = 0;
278     Tim_ManForEachCo( p, pObj, i )
279         pObj->TravId = 0;
280     // create new manager
281     pNew = Tim_ManStart( nNewCis, nNewCos );
282     // copy box connectivity information
283     memcpy( pNew->pCis, p->pCis, sizeof(Tim_Obj_t) * nNewPiNum );
284     memcpy( pNew->pCos + nNewCos - nNewPoNum,
285             p->pCos + Tim_ManCoNum(p) - Tim_ManPoNum(p),
286             sizeof(Tim_Obj_t) * nNewPoNum );
287     // duplicate delay tables
288     if ( Tim_ManDelayTableNum(p) > 0 )
289     {
290         int fWarning = 0;
291         pNew->vDelayTables = Vec_PtrStart( Vec_PtrSize(p->vDelayTables) );
292         Tim_ManForEachTable( p, pDelayTable, i )
293         {
294             if ( pDelayTable == NULL )
295                 continue;
296             if ( i != (int)pDelayTable[0] && fWarning == 0 )
297             {
298                 printf( "Warning: Mismatch in delay-table number between the manager and the box.\n" );
299                 fWarning = 1;
300             }
301             //assert( i == (int)pDelayTable[0] );
302             nInputs   = (int)pDelayTable[1];
303             nOutputs  = (int)pDelayTable[2];
304             pDelayTableNew = ABC_ALLOC( float, 3 + nInputs * nOutputs );
305             pDelayTableNew[0] = i;//(int)pDelayTable[0];
306             pDelayTableNew[1] = (int)pDelayTable[1];
307             pDelayTableNew[2] = (int)pDelayTable[2];
308             for ( k = 0; k < nInputs * nOutputs; k++ )
309                 pDelayTableNew[3+k] = pDelayTable[3+k];
310 //            assert( (int)pDelayTableNew[0] == Vec_PtrSize(pNew->vDelayTables) );
311             assert( Vec_PtrEntry(pNew->vDelayTables, i) == NULL );
312             Vec_PtrWriteEntry( pNew->vDelayTables, i, pDelayTableNew );
313         }
314     }
315     // duplicate boxes
316     if ( Tim_ManBoxNum(p) > 0 )
317     {
318         int curPi = nNewPiNum;
319         int curPo = 0;
320         pNew->vBoxes = Vec_PtrAlloc( Tim_ManBoxNum(p) );
321         Vec_IntForEachEntry( vBoxesLeft, iBox, i )
322         {
323             pBox = Tim_ManBox( p, iBox );
324             Tim_ManCreateBox( pNew, curPo, pBox->nInputs, curPi, pBox->nOutputs, pBox->iDelayTable, pBox->fBlack );
325             Tim_ManBoxSetCopy( pNew, Tim_ManBoxNum(pNew) - 1, Tim_ManBoxCopy(p, iBox) == -1 ? iBox : Tim_ManBoxCopy(p, iBox) );
326             curPi += pBox->nOutputs;
327             curPo += pBox->nInputs;
328         }
329         curPo += nNewPoNum;
330         assert( curPi == Tim_ManCiNum(pNew) );
331         assert( curPo == Tim_ManCoNum(pNew) );
332     }
333     return pNew;
334 }
335 
336 /**Function*************************************************************
337 
338   Synopsis    [Aligns two sets of boxes using the copy field.]
339 
340   Description []
341 
342   SideEffects []
343 
344   SeeAlso     []
345 
346 ***********************************************************************/
Tim_ManAlignTwo(Tim_Man_t * pSpec,Tim_Man_t * pImpl)347 Vec_Int_t * Tim_ManAlignTwo( Tim_Man_t * pSpec, Tim_Man_t * pImpl )
348 {
349     Vec_Int_t * vBoxPres;
350     Tim_Box_t * pBox;
351     int i;
352     assert( Tim_ManBoxNum(pSpec) > Tim_ManBoxNum(pImpl) );
353     // check if boxes of pImpl can be aligned
354     Tim_ManForEachBox( pImpl, pBox, i )
355         if ( pBox->iCopy < 0 || pBox->iCopy >= Tim_ManBoxNum(pSpec) )
356             return NULL;
357     // map dropped boxes into 1, others into 0
358     vBoxPres = Vec_IntStart( Tim_ManBoxNum(pSpec) );
359     Tim_ManForEachBox( pImpl, pBox, i )
360     {
361         assert( !Vec_IntEntry(vBoxPres, pBox->iCopy) );
362         Vec_IntWriteEntry( vBoxPres, pBox->iCopy, 1 );
363     }
364     return vBoxPres;
365 }
366 
367 /**Function*************************************************************
368 
369   Synopsis    [Stops the timing manager.]
370 
371   Description []
372 
373   SideEffects []
374 
375   SeeAlso     []
376 
377 ***********************************************************************/
Tim_ManStop(Tim_Man_t * p)378 void Tim_ManStop( Tim_Man_t * p )
379 {
380     Vec_PtrFreeFree( p->vDelayTables );
381     Vec_PtrFreeP( &p->vBoxes );
382     Mem_FlexStop( p->pMemObj, 0 );
383     ABC_FREE( p->pCis );
384     ABC_FREE( p->pCos );
385     ABC_FREE( p );
386 }
Tim_ManStopP(Tim_Man_t ** p)387 void Tim_ManStopP( Tim_Man_t ** p )
388 {
389     if ( *p == NULL )
390         return;
391     Tim_ManStop( *p );
392     *p = NULL;
393 }
394 
395 /**Function*************************************************************
396 
397   Synopsis    [Creates manager using hierarchy / box library / delay info.]
398 
399   Description []
400 
401   SideEffects []
402 
403   SeeAlso     []
404 
405 ***********************************************************************/
Tim_ManCreate(Tim_Man_t * p,void * pLib,Vec_Flt_t * vInArrs,Vec_Flt_t * vOutReqs)406 void Tim_ManCreate( Tim_Man_t * p, void * pLib, Vec_Flt_t * vInArrs, Vec_Flt_t * vOutReqs )
407 {
408     If_LibBox_t * pLibBox = (If_LibBox_t *)pLib;
409     If_Box_t * pIfBox;
410     Tim_Box_t * pBox;
411     Tim_Obj_t * pObj;
412     float * pTable;
413     int i, k;
414     assert( p->vDelayTables == NULL );
415     p->vDelayTables = pLibBox ? Vec_PtrStart( Vec_PtrSize(pLibBox->vBoxes) ) : Vec_PtrAlloc( 100 );
416     if ( p->vBoxes )
417     Tim_ManForEachBox( p, pBox, i )
418     {
419         if ( pBox->iDelayTable == -1 || pLibBox == NULL )
420         {
421             // create table with constants
422             pTable = ABC_ALLOC( float, 3 + pBox->nInputs * pBox->nOutputs );
423             pTable[0] = pBox->iDelayTable;
424             pTable[1] = pBox->nInputs;
425             pTable[2] = pBox->nOutputs;
426             for ( k = 0; k < pBox->nInputs * pBox->nOutputs; k++ )
427                 pTable[3 + k] = 1.0;
428             // save table
429             pBox->iDelayTable = Vec_PtrSize(p->vDelayTables);
430             Vec_PtrPush( p->vDelayTables, pTable );
431             continue;
432         }
433         assert( pBox->iDelayTable >= 0 && pBox->iDelayTable < Vec_PtrSize(pLibBox->vBoxes) );
434         pIfBox = (If_Box_t *)Vec_PtrEntry( pLibBox->vBoxes, pBox->iDelayTable );
435         assert( pIfBox != NULL );
436         assert( pIfBox->nPis == pBox->nInputs );
437         assert( pIfBox->nPos == pBox->nOutputs );
438         pBox->fBlack = pIfBox->fBlack;
439         if ( Vec_PtrEntry( p->vDelayTables, pBox->iDelayTable ) != NULL )
440             continue;
441         // create table of boxes
442         pTable = ABC_ALLOC( float, 3 + pBox->nInputs * pBox->nOutputs );
443         pTable[0] = pBox->iDelayTable;
444         pTable[1] = pBox->nInputs;
445         pTable[2] = pBox->nOutputs;
446         for ( k = 0; k < pBox->nInputs * pBox->nOutputs; k++ )
447             pTable[3 + k] = pIfBox->pDelays[k];
448         // save table
449         Vec_PtrWriteEntry( p->vDelayTables, pBox->iDelayTable, pTable );
450     }
451     // create arrival times
452     if ( vInArrs )
453     {
454         assert( Vec_FltSize(vInArrs) == Tim_ManPiNum(p) );
455         Tim_ManForEachPi( p, pObj, i )
456             pObj->timeArr = Vec_FltEntry(vInArrs, i);
457 
458     }
459     // create required times
460     if ( vOutReqs )
461     {
462         k = 0;
463         assert( Vec_FltSize(vOutReqs) == Tim_ManPoNum(p) );
464         Tim_ManForEachPo( p, pObj, i )
465             pObj->timeReq = Vec_FltEntry(vOutReqs, k++);
466         assert( k == Tim_ManPoNum(p) );
467     }
468 }
469 
470 
471 /**Function*************************************************************
472 
473   Synopsis    [Get arrival and required times if they are non-trivial.]
474 
475   Description []
476 
477   SideEffects []
478 
479   SeeAlso     []
480 
481 ***********************************************************************/
Tim_ManGetArrTimes(Tim_Man_t * p)482 float * Tim_ManGetArrTimes( Tim_Man_t * p )
483 {
484     float * pTimes;
485     Tim_Obj_t * pObj;
486     int i;
487     Tim_ManForEachPi( p, pObj, i )
488         if ( pObj->timeArr != 0.0 )
489             break;
490     if ( i == Tim_ManPiNum(p) )
491         return NULL;
492     pTimes  = ABC_FALLOC( float, Tim_ManCiNum(p) );
493     Tim_ManForEachPi( p, pObj, i )
494         pTimes[i] = pObj->timeArr;
495     return pTimes;
496 }
Tim_ManGetReqTimes(Tim_Man_t * p)497 float * Tim_ManGetReqTimes( Tim_Man_t * p )
498 {
499     float * pTimes;
500     Tim_Obj_t * pObj;
501     int i, k = 0;
502     Tim_ManForEachPo( p, pObj, i )
503         if ( pObj->timeReq != TIM_ETERNITY )
504             break;
505     if ( i == Tim_ManPoNum(p) )
506         return NULL;
507     pTimes  = ABC_FALLOC( float, Tim_ManCoNum(p) );
508     Tim_ManForEachPo( p, pObj, i )
509         pTimes[k++] = pObj->timeArr;
510     assert( k == Tim_ManPoNum(p) );
511     return pTimes;
512 }
513 
514 
515 /**Function*************************************************************
516 
517   Synopsis    [Prints the timing manager.]
518 
519   Description []
520 
521   SideEffects []
522 
523   SeeAlso     []
524 
525 ***********************************************************************/
Tim_ManPrint(Tim_Man_t * p)526 void Tim_ManPrint( Tim_Man_t * p )
527 {
528     Tim_Box_t * pBox;
529     Tim_Obj_t * pObj, * pPrev;
530     float * pTable;
531     int i, j, k, TableX, TableY;
532     if ( p == NULL )
533         return;
534     printf( "TIMING MANAGER:\n" );
535     printf( "PI = %d. CI = %d. PO = %d. CO = %d. Box = %d.\n",
536         Tim_ManPiNum(p), Tim_ManCiNum(p), Tim_ManPoNum(p), Tim_ManCoNum(p), Tim_ManBoxNum(p) );
537 
538     // print CI info
539     pPrev = p->pCis;
540     Tim_ManForEachPi( p, pObj, i )
541         if ( pPrev->timeArr != pObj->timeArr || pPrev->timeReq != pObj->timeReq )
542             break;
543     if ( i == Tim_ManCiNum(p) )
544         printf( "All PIs     :  arrival = %5.3f  required = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
545     else
546         Tim_ManForEachPi( p, pObj, i )
547             printf( "PI%5d     :  arrival = %5.3f  required = %5.3f\n", i, pObj->timeArr, pObj->timeReq );
548 
549     // print CO info
550     pPrev = p->pCos;
551     Tim_ManForEachPo( p, pObj, i )
552         if ( pPrev->timeArr != pObj->timeArr || pPrev->timeReq != pObj->timeReq )
553             break;
554     if ( i == Tim_ManCoNum(p) )
555         printf( "All POs     :  arrival = %5.3f  required = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
556     else
557     {
558         int k = 0;
559         Tim_ManForEachPo( p, pObj, i )
560             printf( "PO%5d     :  arrival = %5.3f  required = %5.3f\n", k++, pObj->timeArr, pObj->timeReq );
561     }
562 
563     // print box info
564     if ( Tim_ManBoxNum(p) > 0 )
565     Tim_ManForEachBox( p, pBox, i )
566     {
567         printf( "*** Box %5d :  I =%4d. O =%4d. I1 =%6d. O1 =%6d. Table =%4d\n",
568             i, pBox->nInputs, pBox->nOutputs,
569             Tim_ManBoxInputFirst(p, i), Tim_ManBoxOutputFirst(p, i),
570             pBox->iDelayTable );
571 
572         // print box inputs
573         pPrev = Tim_ManBoxInput( p, pBox, 0 );
574         Tim_ManBoxForEachInput( p, pBox, pObj, k )
575             if ( pPrev->timeArr != pObj->timeArr || pPrev->timeReq != pObj->timeReq )
576                 break;
577         if ( k == Tim_ManBoxInputNum(p, pBox->iBox) )
578             printf( "Box inputs  :  arrival = %5.3f  required = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
579         else
580             Tim_ManBoxForEachInput( p, pBox, pObj, k )
581                 printf( "box-in%4d :  arrival = %5.3f  required = %5.3f\n", k, pObj->timeArr, pObj->timeReq );
582 
583         // print box outputs
584         pPrev = Tim_ManBoxOutput( p, pBox, 0 );
585         Tim_ManBoxForEachOutput( p, pBox, pObj, k )
586             if ( pPrev->timeArr != pObj->timeArr || pPrev->timeReq != pObj->timeReq )
587                 break;
588         if ( k == Tim_ManBoxOutputNum(p, pBox->iBox) )
589             printf( "Box outputs :  arrival = %5.3f  required = %5.3f\n", pPrev->timeArr, pPrev->timeReq );
590         else
591             Tim_ManBoxForEachOutput( p, pBox, pObj, k )
592                 printf( "box-out%3d :  arrival = %5.3f  required = %5.3f\n", k, pObj->timeArr, pObj->timeReq );
593 
594         if ( i > 2 )
595             break;
596     }
597 
598     // print delay tables
599     if ( Tim_ManDelayTableNum(p) > 0 )
600     Tim_ManForEachTable( p, pTable, i )
601     {
602         if ( pTable == NULL )
603             continue;
604         printf( "Delay table %d:\n", i );
605         assert( i == (int)pTable[0] );
606         TableX = (int)pTable[1];
607         TableY = (int)pTable[2];
608         for ( j = 0; j < TableY; j++, printf( "\n" ) )
609             for ( k = 0; k < TableX; k++ )
610                 if ( pTable[3+j*TableX+k] == -ABC_INFINITY )
611                     printf( "%5s", "-" );
612                 else
613                     printf( "%5.0f", pTable[3+j*TableX+k] );
614     }
615     printf( "\n" );
616 }
Tim_ManPrintBoxCopy(Tim_Man_t * p)617 void Tim_ManPrintBoxCopy( Tim_Man_t * p )
618 {
619     Tim_Box_t * pBox;
620     int i;
621     if ( p == NULL )
622         return;
623     printf( "TIMING MANAGER:\n" );
624     printf( "PI = %d. CI = %d. PO = %d. CO = %d. Box = %d.\n",
625         Tim_ManPiNum(p), Tim_ManCiNum(p), Tim_ManPoNum(p), Tim_ManCoNum(p), Tim_ManBoxNum(p) );
626 
627     if ( Tim_ManBoxNum(p) > 0 )
628     Tim_ManForEachBox( p, pBox, i )
629         printf( "%d ", pBox->iCopy );
630     printf( "\n" );
631 }
632 
633 /**Function*************************************************************
634 
635   Synopsis    [Prints statistics of the timing manager.]
636 
637   Description []
638 
639   SideEffects []
640 
641   SeeAlso     []
642 
643 ***********************************************************************/
Tim_ManPrintStats(Tim_Man_t * p,int nAnd2Delay)644 void Tim_ManPrintStats( Tim_Man_t * p, int nAnd2Delay )
645 {
646     Tim_Box_t * pBox;
647     Vec_Int_t * vCounts;
648     Vec_Ptr_t * vBoxes;
649     int i, Count, IdMax;
650     if ( p == NULL )
651         return;
652     Abc_Print( 1, "Hierarchy      :  " );
653     printf( "PI/CI = %d/%d   PO/CO = %d/%d   Box = %d   ",
654         Tim_ManPiNum(p), Tim_ManCiNum(p),
655         Tim_ManPoNum(p), Tim_ManCoNum(p),
656         Tim_ManBoxNum(p) );
657     if ( nAnd2Delay )
658         printf( "delay(AND2) = %d", nAnd2Delay );
659     printf( "\n" );
660     if ( Tim_ManBoxNum(p) == 0 )
661         return;
662     IdMax = 0;
663     Tim_ManForEachBox( p, pBox, i )
664         IdMax = Abc_MaxInt( IdMax, pBox->iDelayTable );
665     vCounts = Vec_IntStart( IdMax+1 );
666     vBoxes  = Vec_PtrStart( IdMax+1 );
667     Tim_ManForEachBox( p, pBox, i )
668     {
669         Vec_IntAddToEntry( vCounts, pBox->iDelayTable, 1 );
670         Vec_PtrWriteEntry( vBoxes, pBox->iDelayTable, pBox );
671     }
672     // print statistics about boxes
673     Vec_IntForEachEntry( vCounts, Count, i )
674     {
675         if ( Count == 0 ) continue;
676         pBox = (Tim_Box_t *)Vec_PtrEntry( vBoxes, i );
677         printf( "    Box %4d      ", i );
678         printf( "Num = %4d   ", Count );
679         printf( "Ins = %4d   ", pBox->nInputs );
680         printf( "Outs = %4d",   pBox->nOutputs );
681         printf( "\n" );
682     }
683     Vec_IntFree( vCounts );
684     Vec_PtrFree( vBoxes );
685 }
686 
687 /**Function*************************************************************
688 
689   Synopsis    [Read parameters.]
690 
691   Description []
692 
693   SideEffects []
694 
695   SeeAlso     []
696 
697 ***********************************************************************/
Tim_ManCiNum(Tim_Man_t * p)698 int Tim_ManCiNum( Tim_Man_t * p )
699 {
700     return p->nCis;
701 }
Tim_ManCoNum(Tim_Man_t * p)702 int Tim_ManCoNum( Tim_Man_t * p )
703 {
704     return p->nCos;
705 }
Tim_ManPiNum(Tim_Man_t * p)706 int Tim_ManPiNum( Tim_Man_t * p )
707 {
708     if ( Tim_ManBoxNum(p) == 0 )
709         return Tim_ManCiNum(p);
710     return Tim_ManBoxOutputFirst(p, 0);
711 }
Tim_ManPoNum(Tim_Man_t * p)712 int Tim_ManPoNum( Tim_Man_t * p )
713 {
714     int iLastBoxId;
715     if ( Tim_ManBoxNum(p) == 0 )
716         return Tim_ManCoNum(p);
717     iLastBoxId = Tim_ManBoxNum(p) - 1;
718     return Tim_ManCoNum(p) - (Tim_ManBoxInputFirst(p, iLastBoxId) + Tim_ManBoxInputNum(p, iLastBoxId));
719 }
Tim_ManBoxNum(Tim_Man_t * p)720 int Tim_ManBoxNum( Tim_Man_t * p )
721 {
722     return p->vBoxes ? Vec_PtrSize(p->vBoxes) : 0;
723 }
Tim_ManBlackBoxNum(Tim_Man_t * p)724 int Tim_ManBlackBoxNum( Tim_Man_t * p )
725 {
726     Tim_Box_t * pBox;
727     int i, Counter = 0;
728     if ( Tim_ManBoxNum(p) )
729         Tim_ManForEachBox( p, pBox, i )
730             Counter += pBox->fBlack;
731     return Counter;
732 }
Tim_ManBlackBoxIoNum(Tim_Man_t * p,int * pnBbIns,int * pnBbOuts)733 void Tim_ManBlackBoxIoNum( Tim_Man_t * p, int * pnBbIns, int * pnBbOuts )
734 {
735     Tim_Box_t * pBox;
736     int i;
737     *pnBbIns = *pnBbOuts = 0;
738     if ( Tim_ManBoxNum(p) )
739         Tim_ManForEachBox( p, pBox, i )
740         {
741             if ( !pBox->fBlack )//&& pBox->nInputs <= 6 )
742                 continue;
743             *pnBbIns  += Tim_ManBoxInputNum( p, i );
744             *pnBbOuts += Tim_ManBoxOutputNum( p, i );
745         }
746 }
Tim_ManDelayTableNum(Tim_Man_t * p)747 int Tim_ManDelayTableNum( Tim_Man_t * p )
748 {
749     return p->vDelayTables ? Vec_PtrSize(p->vDelayTables) : 0;
750 }
751 
752 /**Function*************************************************************
753 
754   Synopsis    [Sets the vector of timing tables associated with the manager.]
755 
756   Description []
757 
758   SideEffects []
759 
760   SeeAlso     []
761 
762 ***********************************************************************/
Tim_ManSetDelayTables(Tim_Man_t * p,Vec_Ptr_t * vDelayTables)763 void Tim_ManSetDelayTables( Tim_Man_t * p, Vec_Ptr_t * vDelayTables )
764 {
765     assert( p->vDelayTables == NULL );
766     p->vDelayTables = vDelayTables;
767 }
768 
769 /**Function*************************************************************
770 
771   Synopsis    [Disables the use of the traversal ID.]
772 
773   Description []
774 
775   SideEffects []
776 
777   SeeAlso     []
778 
779 ***********************************************************************/
Tim_ManTravIdDisable(Tim_Man_t * p)780 void Tim_ManTravIdDisable( Tim_Man_t * p )
781 {
782     p->fUseTravId = 0;
783 }
784 
785 /**Function*************************************************************
786 
787   Synopsis    [Enables the use of the traversal ID.]
788 
789   Description []
790 
791   SideEffects []
792 
793   SeeAlso     []
794 
795 ***********************************************************************/
Tim_ManTravIdEnable(Tim_Man_t * p)796 void Tim_ManTravIdEnable( Tim_Man_t * p )
797 {
798     p->fUseTravId = 1;
799 }
800 
801 ////////////////////////////////////////////////////////////////////////
802 ///                       END OF FILE                                ///
803 ////////////////////////////////////////////////////////////////////////
804 
805 
806 ABC_NAMESPACE_IMPL_END
807 
808