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