1 /**CFile****************************************************************
2
3 FileName [ifCut.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [FPGA mapping based on priority cuts.]
8
9 Synopsis [Cut computation.]
10
11 Author [Alan Mishchenko]
12
13 Affiliation [UC Berkeley]
14
15 Date [Ver. 1.0. Started - November 21, 2006.]
16
17 Revision [$Id: ifCut.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
18
19 ***********************************************************************/
20
21 #include "if.h"
22
23 ABC_NAMESPACE_IMPL_START
24
25
26 ////////////////////////////////////////////////////////////////////////
27 /// DECLARATIONS ///
28 ////////////////////////////////////////////////////////////////////////
29
30 ////////////////////////////////////////////////////////////////////////
31 /// FUNCTION DEFINITIONS ///
32 ////////////////////////////////////////////////////////////////////////
33
34 /**Function*************************************************************
35
36 Synopsis [Check correctness of cuts.]
37
38 Description []
39
40 SideEffects []
41
42 SeeAlso []
43
44 ***********************************************************************/
If_CutVerifyCut(If_Cut_t * pBase,If_Cut_t * pCut)45 static inline int If_CutVerifyCut( If_Cut_t * pBase, If_Cut_t * pCut ) // check if pCut is contained in pBase
46 {
47 int nSizeB = pBase->nLeaves;
48 int nSizeC = pCut->nLeaves;
49 int * pB = pBase->pLeaves;
50 int * pC = pCut->pLeaves;
51 int i, k;
52 for ( i = 0; i < nSizeC; i++ )
53 {
54 for ( k = 0; k < nSizeB; k++ )
55 if ( pC[i] == pB[k] )
56 break;
57 if ( k == nSizeB )
58 return 0;
59 }
60 return 1;
61 }
If_CutVerifyCuts(If_Set_t * pCutSet,int fOrdered)62 int If_CutVerifyCuts( If_Set_t * pCutSet, int fOrdered )
63 {
64 static int Count = 0;
65 If_Cut_t * pCut0, * pCut1;
66 int i, k, m, n, Value;
67 assert( pCutSet->nCuts > 0 );
68 for ( i = 0; i < pCutSet->nCuts; i++ )
69 {
70 pCut0 = pCutSet->ppCuts[i];
71 assert( pCut0->uSign == If_ObjCutSignCompute(pCut0) );
72 if ( fOrdered )
73 {
74 // check duplicates
75 for ( m = 1; m < (int)pCut0->nLeaves; m++ )
76 assert( pCut0->pLeaves[m-1] < pCut0->pLeaves[m] );
77 }
78 else
79 {
80 // check duplicates
81 for ( m = 0; m < (int)pCut0->nLeaves; m++ )
82 for ( n = m+1; n < (int)pCut0->nLeaves; n++ )
83 assert( pCut0->pLeaves[m] != pCut0->pLeaves[n] );
84 }
85 // check pairs
86 for ( k = 0; k < pCutSet->nCuts; k++ )
87 {
88 pCut1 = pCutSet->ppCuts[k];
89 if ( pCut0 == pCut1 )
90 continue;
91 Count++;
92 // check containments
93 Value = If_CutVerifyCut( pCut0, pCut1 );
94 // assert( Value == 0 );
95 if ( Value )
96 {
97 assert( pCut0->uSign == If_ObjCutSignCompute(pCut0) );
98 assert( pCut1->uSign == If_ObjCutSignCompute(pCut1) );
99 If_CutPrint( pCut0 );
100 If_CutPrint( pCut1 );
101 assert( 0 );
102 }
103 }
104 }
105 return 1;
106 }
107
108 /**Function*************************************************************
109
110 Synopsis [Returns 1 if pDom is contained in pCut.]
111
112 Description []
113
114 SideEffects []
115
116 SeeAlso []
117
118 ***********************************************************************/
If_CutCheckDominance(If_Cut_t * pDom,If_Cut_t * pCut)119 static inline int If_CutCheckDominance( If_Cut_t * pDom, If_Cut_t * pCut )
120 {
121 int i, k;
122 assert( pDom->nLeaves <= pCut->nLeaves );
123 for ( i = 0; i < (int)pDom->nLeaves; i++ )
124 {
125 for ( k = 0; k < (int)pCut->nLeaves; k++ )
126 if ( pDom->pLeaves[i] == pCut->pLeaves[k] )
127 break;
128 if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut
129 return 0;
130 }
131 // every node in pDom is contained in pCut
132 return 1;
133 }
134
135 /**Function*************************************************************
136
137 Synopsis [Returns 1 if the cut is contained.]
138
139 Description []
140
141 SideEffects []
142
143 SeeAlso []
144
145 ***********************************************************************/
If_CutFilter(If_Set_t * pCutSet,If_Cut_t * pCut,int fSaveCut0)146 int If_CutFilter( If_Set_t * pCutSet, If_Cut_t * pCut, int fSaveCut0 )
147 {
148 If_Cut_t * pTemp;
149 int i, k;
150 assert( pCutSet->ppCuts[pCutSet->nCuts] == pCut );
151 for ( i = 0; i < pCutSet->nCuts; i++ )
152 {
153 pTemp = pCutSet->ppCuts[i];
154 if ( pTemp->nLeaves > pCut->nLeaves )
155 {
156 // do not fiter the first cut
157 if ( i == 0 && ((pCutSet->nCuts > 1 && pCutSet->ppCuts[1]->fUseless) || (fSaveCut0 && pCutSet->nCuts == 1)) )
158 continue;
159 // skip the non-contained cuts
160 if ( (pTemp->uSign & pCut->uSign) != pCut->uSign )
161 continue;
162 // check containment seriously
163 if ( If_CutCheckDominance( pCut, pTemp ) )
164 {
165 // p->ppCuts[i] = p->ppCuts[p->nCuts-1];
166 // p->ppCuts[p->nCuts-1] = pTemp;
167 // p->nCuts--;
168 // i--;
169 // remove contained cut
170 for ( k = i; k < pCutSet->nCuts; k++ )
171 pCutSet->ppCuts[k] = pCutSet->ppCuts[k+1];
172 pCutSet->ppCuts[pCutSet->nCuts] = pTemp;
173 pCutSet->nCuts--;
174 i--;
175 }
176 }
177 else
178 {
179 // skip the non-contained cuts
180 if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign )
181 continue;
182 // check containment seriously
183 if ( If_CutCheckDominance( pTemp, pCut ) )
184 return 1;
185 }
186 }
187 return 0;
188 }
189
190 /**Function*************************************************************
191
192 Synopsis [Prepares the object for FPGA mapping.]
193
194 Description []
195
196 SideEffects []
197
198 SeeAlso []
199
200 ***********************************************************************/
If_CutMergeOrdered_(If_Man_t * p,If_Cut_t * pC0,If_Cut_t * pC1,If_Cut_t * pC)201 int If_CutMergeOrdered_( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC )
202 {
203 int nSizeC0 = pC0->nLeaves;
204 int nSizeC1 = pC1->nLeaves;
205 int nLimit = pC0->nLimit;
206 int i, k, c, s;
207
208 // both cuts are the largest
209 if ( nSizeC0 == nLimit && nSizeC1 == nLimit )
210 {
211 for ( i = 0; i < nSizeC0; i++ )
212 {
213 if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
214 return 0;
215 p->pPerm[0][i] = p->pPerm[1][i] = p->pPerm[2][i] = i;
216 pC->pLeaves[i] = pC0->pLeaves[i];
217 }
218 pC->nLeaves = nLimit;
219 pC->uSign = pC0->uSign | pC1->uSign;
220 p->uSharedMask = Abc_InfoMask( nLimit );
221 return 1;
222 }
223
224 // compare two cuts with different numbers
225 i = k = c = s = 0;
226 p->uSharedMask = 0;
227 if ( nSizeC0 == 0 ) goto FlushCut1;
228 if ( nSizeC1 == 0 ) goto FlushCut0;
229 while ( 1 )
230 {
231 if ( c == nLimit ) return 0;
232 if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
233 {
234 p->pPerm[0][i] = c;
235 pC->pLeaves[c++] = pC0->pLeaves[i++];
236 if ( i == nSizeC0 ) goto FlushCut1;
237 }
238 else if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
239 {
240 p->pPerm[1][k] = c;
241 pC->pLeaves[c++] = pC1->pLeaves[k++];
242 if ( k == nSizeC1 ) goto FlushCut0;
243 }
244 else
245 {
246 p->uSharedMask |= (1 << c);
247 p->pPerm[0][i] = p->pPerm[1][k] = p->pPerm[2][s++] = c;
248 pC->pLeaves[c++] = pC0->pLeaves[i++]; k++;
249 if ( i == nSizeC0 ) goto FlushCut1;
250 if ( k == nSizeC1 ) goto FlushCut0;
251 }
252 }
253
254 FlushCut0:
255 if ( c + nSizeC0 > nLimit + i ) return 0;
256 while ( i < nSizeC0 )
257 {
258 p->pPerm[0][i] = c;
259 pC->pLeaves[c++] = pC0->pLeaves[i++];
260 }
261 pC->nLeaves = c;
262 pC->uSign = pC0->uSign | pC1->uSign;
263 assert( c > 0 );
264 return 1;
265
266 FlushCut1:
267 if ( c + nSizeC1 > nLimit + k ) return 0;
268 while ( k < nSizeC1 )
269 {
270 p->pPerm[1][k] = c;
271 pC->pLeaves[c++] = pC1->pLeaves[k++];
272 }
273 pC->nLeaves = c;
274 pC->uSign = pC0->uSign | pC1->uSign;
275 assert( c > 0 );
276 return 1;
277 }
278
279 /**Function*************************************************************
280
281 Synopsis [Prepares the object for FPGA mapping.]
282
283 Description []
284
285 SideEffects []
286
287 SeeAlso []
288
289 ***********************************************************************/
If_CutMergeOrdered(If_Man_t * p,If_Cut_t * pC0,If_Cut_t * pC1,If_Cut_t * pC)290 int If_CutMergeOrdered( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC )
291 {
292 int nSizeC0 = pC0->nLeaves;
293 int nSizeC1 = pC1->nLeaves;
294 int nLimit = pC0->nLimit;
295 int i, k, c, s;
296
297 // both cuts are the largest
298 if ( nSizeC0 == nLimit && nSizeC1 == nLimit )
299 {
300 for ( i = 0; i < nSizeC0; i++ )
301 {
302 if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
303 return 0;
304 pC->pLeaves[i] = pC0->pLeaves[i];
305 }
306 pC->nLeaves = nLimit;
307 pC->uSign = pC0->uSign | pC1->uSign;
308 return 1;
309 }
310
311 // compare two cuts with different numbers
312 i = k = c = s = 0;
313 if ( nSizeC0 == 0 ) goto FlushCut1;
314 if ( nSizeC1 == 0 ) goto FlushCut0;
315 while ( 1 )
316 {
317 if ( c == nLimit ) return 0;
318 if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
319 {
320 pC->pLeaves[c++] = pC0->pLeaves[i++];
321 if ( i == nSizeC0 ) goto FlushCut1;
322 }
323 else if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
324 {
325 pC->pLeaves[c++] = pC1->pLeaves[k++];
326 if ( k == nSizeC1 ) goto FlushCut0;
327 }
328 else
329 {
330 pC->pLeaves[c++] = pC0->pLeaves[i++]; k++;
331 if ( i == nSizeC0 ) goto FlushCut1;
332 if ( k == nSizeC1 ) goto FlushCut0;
333 }
334 }
335
336 FlushCut0:
337 if ( c + nSizeC0 > nLimit + i ) return 0;
338 while ( i < nSizeC0 )
339 pC->pLeaves[c++] = pC0->pLeaves[i++];
340 pC->nLeaves = c;
341 pC->uSign = pC0->uSign | pC1->uSign;
342 return 1;
343
344 FlushCut1:
345 if ( c + nSizeC1 > nLimit + k ) return 0;
346 while ( k < nSizeC1 )
347 pC->pLeaves[c++] = pC1->pLeaves[k++];
348 pC->nLeaves = c;
349 pC->uSign = pC0->uSign | pC1->uSign;
350 return 1;
351 }
352
353 /**Function*************************************************************
354
355 Synopsis [Prepares the object for FPGA mapping.]
356
357 Description []
358
359 SideEffects []
360
361 SeeAlso []
362
363 ***********************************************************************/
If_CutMerge(If_Man_t * p,If_Cut_t * pCut0,If_Cut_t * pCut1,If_Cut_t * pCut)364 int If_CutMerge( If_Man_t * p, If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut )
365 {
366 int nLutSize = pCut0->nLimit;
367 int nSize0 = pCut0->nLeaves;
368 int nSize1 = pCut1->nLeaves;
369 int * pC0 = pCut0->pLeaves;
370 int * pC1 = pCut1->pLeaves;
371 int * pC = pCut->pLeaves;
372 int i, k, c;
373 // compare two cuts with different numbers
374 c = nSize0;
375 for ( i = 0; i < nSize1; i++ )
376 {
377 for ( k = 0; k < nSize0; k++ )
378 if ( pC1[i] == pC0[k] )
379 break;
380 if ( k < nSize0 )
381 {
382 p->pPerm[1][i] = k;
383 continue;
384 }
385 if ( c == nLutSize )
386 return 0;
387 p->pPerm[1][i] = c;
388 pC[c++] = pC1[i];
389 }
390 for ( i = 0; i < nSize0; i++ )
391 pC[i] = pC0[i];
392 pCut->nLeaves = c;
393 pCut->uSign = pCut0->uSign | pCut1->uSign;
394 return 1;
395 }
396
397 /**Function*************************************************************
398
399 Synopsis [Prepares the object for FPGA mapping.]
400
401 Description []
402
403 SideEffects []
404
405 SeeAlso []
406
407 ***********************************************************************/
If_CutCompareDelay(If_Man_t * p,If_Cut_t ** ppC0,If_Cut_t ** ppC1)408 int If_CutCompareDelay( If_Man_t * p, If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
409 {
410 If_Cut_t * pC0 = *ppC0;
411 If_Cut_t * pC1 = *ppC1;
412 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
413 return -1;
414 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
415 return 1;
416 if ( pC0->nLeaves < pC1->nLeaves )
417 return -1;
418 if ( pC0->nLeaves > pC1->nLeaves )
419 return 1;
420 if ( pC0->Area < pC1->Area - p->fEpsilon )
421 return -1;
422 if ( pC0->Area > pC1->Area + p->fEpsilon )
423 return 1;
424 return 0;
425 }
426
427 /**Function*************************************************************
428
429 Synopsis [Prepares the object for FPGA mapping.]
430
431 Description []
432
433 SideEffects []
434
435 SeeAlso []
436
437 ***********************************************************************/
If_CutCompareDelayOld(If_Man_t * p,If_Cut_t ** ppC0,If_Cut_t ** ppC1)438 int If_CutCompareDelayOld( If_Man_t * p, If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
439 {
440 If_Cut_t * pC0 = *ppC0;
441 If_Cut_t * pC1 = *ppC1;
442 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
443 return -1;
444 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
445 return 1;
446 if ( pC0->Area < pC1->Area - p->fEpsilon )
447 return -1;
448 if ( pC0->Area > pC1->Area + p->fEpsilon )
449 return 1;
450 if ( pC0->nLeaves < pC1->nLeaves )
451 return -1;
452 if ( pC0->nLeaves > pC1->nLeaves )
453 return 1;
454 return 0;
455 }
456
457 /**Function*************************************************************
458
459 Synopsis [Prepares the object for FPGA mapping.]
460
461 Description []
462
463 SideEffects []
464
465 SeeAlso []
466
467 ***********************************************************************/
If_CutCompareArea(If_Man_t * p,If_Cut_t ** ppC0,If_Cut_t ** ppC1)468 int If_CutCompareArea( If_Man_t * p, If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
469 {
470 If_Cut_t * pC0 = *ppC0;
471 If_Cut_t * pC1 = *ppC1;
472 if ( pC0->Area < pC1->Area - p->fEpsilon )
473 return -1;
474 if ( pC0->Area > pC1->Area + p->fEpsilon )
475 return 1;
476 // if ( pC0->AveRefs > pC1->AveRefs )
477 // return -1;
478 // if ( pC0->AveRefs < pC1->AveRefs )
479 // return 1;
480 if ( pC0->nLeaves < pC1->nLeaves )
481 return -1;
482 if ( pC0->nLeaves > pC1->nLeaves )
483 return 1;
484 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
485 return -1;
486 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
487 return 1;
488 return 0;
489 }
490
491 /**Function*************************************************************
492
493 Synopsis [Comparison function for two cuts.]
494
495 Description []
496
497 SideEffects []
498
499 SeeAlso []
500
501 ***********************************************************************/
If_ManSortCompare(If_Man_t * p,If_Cut_t * pC0,If_Cut_t * pC1)502 static inline int If_ManSortCompare( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1 )
503 {
504 if ( p->pPars->fPower )
505 {
506 if ( p->SortMode == 1 ) // area flow
507 {
508 if ( pC0->Area < pC1->Area - p->fEpsilon )
509 return -1;
510 if ( pC0->Area > pC1->Area + p->fEpsilon )
511 return 1;
512 //Abc_Print( 1,"area(%.2f, %.2f), power(%.2f, %.2f), edge(%.2f, %.2f)\n",
513 // pC0->Area, pC1->Area, pC0->Power, pC1->Power, pC0->Edge, pC1->Edge);
514 if ( pC0->Power < pC1->Power - p->fEpsilon )
515 return -1;
516 if ( pC0->Power > pC1->Power + p->fEpsilon )
517 return 1;
518 if ( pC0->Edge < pC1->Edge - p->fEpsilon )
519 return -1;
520 if ( pC0->Edge > pC1->Edge + p->fEpsilon )
521 return 1;
522 // if ( pC0->AveRefs > pC1->AveRefs )
523 // return -1;
524 // if ( pC0->AveRefs < pC1->AveRefs )
525 // return 1;
526 if ( pC0->nLeaves < pC1->nLeaves )
527 return -1;
528 if ( pC0->nLeaves > pC1->nLeaves )
529 return 1;
530 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
531 return -1;
532 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
533 return 1;
534 return 0;
535 }
536 if ( p->SortMode == 0 ) // delay
537 {
538 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
539 return -1;
540 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
541 return 1;
542 if ( pC0->nLeaves < pC1->nLeaves )
543 return -1;
544 if ( pC0->nLeaves > pC1->nLeaves )
545 return 1;
546 if ( pC0->Area < pC1->Area - p->fEpsilon )
547 return -1;
548 if ( pC0->Area > pC1->Area + p->fEpsilon )
549 return 1;
550 if ( pC0->Power < pC1->Power - p->fEpsilon )
551 return -1;
552 if ( pC0->Power > pC1->Power + p->fEpsilon )
553 return 1;
554 if ( pC0->Edge < pC1->Edge - p->fEpsilon )
555 return -1;
556 if ( pC0->Edge > pC1->Edge + p->fEpsilon )
557 return 1;
558 return 0;
559 }
560 assert( p->SortMode == 2 ); // delay old, exact area
561 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
562 return -1;
563 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
564 return 1;
565 if ( pC0->Power < pC1->Power - p->fEpsilon )
566 return -1;
567 if ( pC0->Power > pC1->Power + p->fEpsilon )
568 return 1;
569 if ( pC0->Edge < pC1->Edge - p->fEpsilon )
570 return -1;
571 if ( pC0->Edge > pC1->Edge + p->fEpsilon )
572 return 1;
573 if ( pC0->Area < pC1->Area - p->fEpsilon )
574 return -1;
575 if ( pC0->Area > pC1->Area + p->fEpsilon )
576 return 1;
577 if ( pC0->nLeaves < pC1->nLeaves )
578 return -1;
579 if ( pC0->nLeaves > pC1->nLeaves )
580 return 1;
581 return 0;
582 }
583 else // regular
584 {
585 if ( p->SortMode == 1 ) // area
586 {
587 if ( pC0->Area < pC1->Area - p->fEpsilon )
588 return -1;
589 if ( pC0->Area > pC1->Area + p->fEpsilon )
590 return 1;
591 if ( pC0->Edge < pC1->Edge - p->fEpsilon )
592 return -1;
593 if ( pC0->Edge > pC1->Edge + p->fEpsilon )
594 return 1;
595 if ( pC0->Power < pC1->Power - p->fEpsilon )
596 return -1;
597 if ( pC0->Power > pC1->Power + p->fEpsilon )
598 return 1;
599 // if ( pC0->AveRefs > pC1->AveRefs )
600 // return -1;
601 // if ( pC0->AveRefs < pC1->AveRefs )
602 // return 1;
603 if ( pC0->nLeaves < pC1->nLeaves )
604 return -1;
605 if ( pC0->nLeaves > pC1->nLeaves )
606 return 1;
607 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
608 return -1;
609 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
610 return 1;
611 return 0;
612 }
613 if ( p->SortMode == 0 ) // delay
614 {
615 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
616 return -1;
617 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
618 return 1;
619 if ( pC0->nLeaves < pC1->nLeaves )
620 return -1;
621 if ( pC0->nLeaves > pC1->nLeaves )
622 return 1;
623 if ( pC0->Area < pC1->Area - p->fEpsilon )
624 return -1;
625 if ( pC0->Area > pC1->Area + p->fEpsilon )
626 return 1;
627 if ( pC0->Edge < pC1->Edge - p->fEpsilon )
628 return -1;
629 if ( pC0->Edge > pC1->Edge + p->fEpsilon )
630 return 1;
631 if ( pC0->Power < pC1->Power - p->fEpsilon )
632 return -1;
633 if ( pC0->Power > pC1->Power + p->fEpsilon )
634 return 1;
635 return 0;
636 }
637 assert( p->SortMode == 2 ); // delay old
638 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
639 return -1;
640 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
641 return 1;
642 if ( pC0->Area < pC1->Area - p->fEpsilon )
643 return -1;
644 if ( pC0->Area > pC1->Area + p->fEpsilon )
645 return 1;
646 if ( pC0->Edge < pC1->Edge - p->fEpsilon )
647 return -1;
648 if ( pC0->Edge > pC1->Edge + p->fEpsilon )
649 return 1;
650 if ( pC0->Power < pC1->Power - p->fEpsilon )
651 return -1;
652 if ( pC0->Power > pC1->Power + p->fEpsilon )
653 return 1;
654 if ( pC0->nLeaves < pC1->nLeaves )
655 return -1;
656 if ( pC0->nLeaves > pC1->nLeaves )
657 return 1;
658 return 0;
659 }
660 }
661
662 /**Function*************************************************************
663
664 Synopsis [Comparison function for two cuts.]
665
666 Description []
667
668 SideEffects []
669
670 SeeAlso []
671
672 ***********************************************************************/
If_ManSortCompare_old(If_Man_t * p,If_Cut_t * pC0,If_Cut_t * pC1)673 static inline int If_ManSortCompare_old( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1 )
674 {
675 if ( p->SortMode == 1 ) // area
676 {
677 if ( pC0->Area < pC1->Area - p->fEpsilon )
678 return -1;
679 if ( pC0->Area > pC1->Area + p->fEpsilon )
680 return 1;
681 // if ( pC0->AveRefs > pC1->AveRefs )
682 // return -1;
683 // if ( pC0->AveRefs < pC1->AveRefs )
684 // return 1;
685 if ( pC0->nLeaves < pC1->nLeaves )
686 return -1;
687 if ( pC0->nLeaves > pC1->nLeaves )
688 return 1;
689 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
690 return -1;
691 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
692 return 1;
693 return 0;
694 }
695 if ( p->SortMode == 0 ) // delay
696 {
697 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
698 return -1;
699 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
700 return 1;
701 if ( pC0->nLeaves < pC1->nLeaves )
702 return -1;
703 if ( pC0->nLeaves > pC1->nLeaves )
704 return 1;
705 if ( pC0->Area < pC1->Area - p->fEpsilon )
706 return -1;
707 if ( pC0->Area > pC1->Area + p->fEpsilon )
708 return 1;
709 return 0;
710 }
711 assert( p->SortMode == 2 ); // delay old
712 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
713 return -1;
714 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
715 return 1;
716 if ( pC0->Area < pC1->Area - p->fEpsilon )
717 return -1;
718 if ( pC0->Area > pC1->Area + p->fEpsilon )
719 return 1;
720 if ( pC0->nLeaves < pC1->nLeaves )
721 return -1;
722 if ( pC0->nLeaves > pC1->nLeaves )
723 return 1;
724 return 0;
725 }
726
727 /**Function*************************************************************
728
729 Synopsis [Performs incremental sorting of cuts.]
730
731 Description [Currently only the trivial sorting is implemented.]
732
733 SideEffects []
734
735 SeeAlso []
736
737 ***********************************************************************/
If_CutSort(If_Man_t * p,If_Set_t * pCutSet,If_Cut_t * pCut)738 void If_CutSort( If_Man_t * p, If_Set_t * pCutSet, If_Cut_t * pCut )
739 {
740 // int Counter = 0;
741 int i;
742
743 // the new cut is the last one
744 assert( pCutSet->ppCuts[pCutSet->nCuts] == pCut );
745 assert( pCutSet->nCuts <= pCutSet->nCutsMax );
746
747 // cut structure is empty
748 if ( pCutSet->nCuts == 0 )
749 {
750 pCutSet->nCuts++;
751 return;
752 }
753
754 if ( !pCut->fUseless &&
755 (p->pPars->fUseDsd || p->pPars->pFuncCell2 || p->pPars->fUseBat ||
756 p->pPars->pLutStruct || p->pPars->fUserRecLib || p->pPars->fUserSesLib ||
757 p->pPars->fEnableCheck07 || p->pPars->fUseCofVars || p->pPars->fUseAndVars || p->pPars->fUse34Spec ||
758 p->pPars->fUseDsdTune || p->pPars->fEnableCheck75 || p->pPars->fEnableCheck75u) )
759 {
760 If_Cut_t * pFirst = pCutSet->ppCuts[0];
761 if ( pFirst->fUseless || If_ManSortCompare(p, pFirst, pCut) == 1 )
762 {
763 pCutSet->ppCuts[0] = pCut;
764 pCutSet->ppCuts[pCutSet->nCuts] = pFirst;
765 If_CutSort( p, pCutSet, pFirst );
766 return;
767 }
768 }
769
770 // the cut will be added - find its place
771 for ( i = pCutSet->nCuts-1; i >= 0; i-- )
772 {
773 // Counter++;
774 if ( If_ManSortCompare( p, pCutSet->ppCuts[i], pCut ) <= 0 || (i == 0 && !pCutSet->ppCuts[0]->fUseless && pCut->fUseless) )
775 break;
776 pCutSet->ppCuts[i+1] = pCutSet->ppCuts[i];
777 pCutSet->ppCuts[i] = pCut;
778 }
779 // Abc_Print( 1, "%d ", Counter );
780
781 // update the number of cuts
782 if ( pCutSet->nCuts < pCutSet->nCutsMax )
783 pCutSet->nCuts++;
784 }
785
786 /**Function*************************************************************
787
788 Synopsis [Orders the leaves of the cut.]
789
790 Description []
791
792 SideEffects []
793
794 SeeAlso []
795
796 ***********************************************************************/
If_CutOrder(If_Cut_t * pCut)797 void If_CutOrder( If_Cut_t * pCut )
798 {
799 int i, Temp, fChanges;
800 do {
801 fChanges = 0;
802 for ( i = 0; i < (int)pCut->nLeaves - 1; i++ )
803 {
804 assert( pCut->pLeaves[i] != pCut->pLeaves[i+1] );
805 if ( pCut->pLeaves[i] <= pCut->pLeaves[i+1] )
806 continue;
807 Temp = pCut->pLeaves[i];
808 pCut->pLeaves[i] = pCut->pLeaves[i+1];
809 pCut->pLeaves[i+1] = Temp;
810 fChanges = 1;
811 }
812 } while ( fChanges );
813 }
814
815 /**Function*************************************************************
816
817 Synopsis [Checks correctness of the cut.]
818
819 Description []
820
821 SideEffects []
822
823 SeeAlso []
824
825 ***********************************************************************/
If_CutCheck(If_Cut_t * pCut)826 int If_CutCheck( If_Cut_t * pCut )
827 {
828 int i;
829 assert( pCut->nLeaves <= pCut->nLimit );
830 if ( pCut->nLeaves < 2 )
831 return 1;
832 for ( i = 1; i < (int)pCut->nLeaves; i++ )
833 {
834 if ( pCut->pLeaves[i-1] >= pCut->pLeaves[i] )
835 {
836 Abc_Print( -1, "If_CutCheck(): Cut has wrong ordering of inputs.\n" );
837 return 0;
838 }
839 assert( pCut->pLeaves[i-1] < pCut->pLeaves[i] );
840 }
841 return 1;
842 }
843
844
845 /**Function*************************************************************
846
847 Synopsis [Prints one cut.]
848
849 Description []
850
851 SideEffects []
852
853 SeeAlso []
854
855 ***********************************************************************/
If_CutPrint(If_Cut_t * pCut)856 void If_CutPrint( If_Cut_t * pCut )
857 {
858 unsigned i;
859 Abc_Print( 1, "{" );
860 for ( i = 0; i < pCut->nLeaves; i++ )
861 Abc_Print( 1, " %s%d", If_CutLeafBit(pCut, i) ? "!":"", pCut->pLeaves[i] );
862 Abc_Print( 1, " }\n" );
863 }
864
865 /**Function*************************************************************
866
867 Synopsis [Prints one cut.]
868
869 Description []
870
871 SideEffects []
872
873 SeeAlso []
874
875 ***********************************************************************/
If_CutPrintTiming(If_Man_t * p,If_Cut_t * pCut)876 void If_CutPrintTiming( If_Man_t * p, If_Cut_t * pCut )
877 {
878 If_Obj_t * pLeaf;
879 unsigned i;
880 Abc_Print( 1, "{" );
881 If_CutForEachLeaf( p, pCut, pLeaf, i )
882 Abc_Print( 1, " %d(%.2f/%.2f)", pLeaf->Id, If_ObjCutBest(pLeaf)->Delay, pLeaf->Required );
883 Abc_Print( 1, " }\n" );
884 }
885
886 /**Function*************************************************************
887
888 Synopsis [Moves the cut over the latch.]
889
890 Description []
891
892 SideEffects []
893
894 SeeAlso []
895
896 ***********************************************************************/
If_CutLift(If_Cut_t * pCut)897 void If_CutLift( If_Cut_t * pCut )
898 {
899 unsigned i;
900 for ( i = 0; i < pCut->nLeaves; i++ )
901 {
902 assert( (pCut->pLeaves[i] & 255) < 255 );
903 pCut->pLeaves[i]++;
904 }
905 }
906
907
908 /**Function*************************************************************
909
910 Synopsis [Computes area flow.]
911
912 Description []
913
914 SideEffects []
915
916 SeeAlso []
917
918 ***********************************************************************/
If_CutAreaFlow(If_Man_t * p,If_Cut_t * pCut)919 float If_CutAreaFlow( If_Man_t * p, If_Cut_t * pCut )
920 {
921 If_Obj_t * pLeaf;
922 float Flow, AddOn;
923 int i;
924 Flow = If_CutLutArea(p, pCut);
925 If_CutForEachLeaf( p, pCut, pLeaf, i )
926 {
927 if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
928 AddOn = If_ObjCutBest(pLeaf)->Area;
929 else
930 {
931 assert( pLeaf->EstRefs > p->fEpsilon );
932 AddOn = If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs;
933 }
934 if ( Flow >= (float)1e32 || AddOn >= (float)1e32 )
935 Flow = (float)1e32;
936 else
937 {
938 Flow += AddOn;
939 if ( Flow > (float)1e32 )
940 Flow = (float)1e32;
941 }
942 }
943 return Flow;
944 }
945
946 /**Function*************************************************************
947
948 Synopsis [Computes area flow.]
949
950 Description []
951
952 SideEffects []
953
954 SeeAlso []
955
956 ***********************************************************************/
If_CutEdgeFlow(If_Man_t * p,If_Cut_t * pCut)957 float If_CutEdgeFlow( If_Man_t * p, If_Cut_t * pCut )
958 {
959 If_Obj_t * pLeaf;
960 float Flow, AddOn;
961 int i;
962 Flow = pCut->nLeaves;
963 If_CutForEachLeaf( p, pCut, pLeaf, i )
964 {
965 if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
966 AddOn = If_ObjCutBest(pLeaf)->Edge;
967 else
968 {
969 assert( pLeaf->EstRefs > p->fEpsilon );
970 AddOn = If_ObjCutBest(pLeaf)->Edge / pLeaf->EstRefs;
971 }
972 if ( Flow >= (float)1e32 || AddOn >= (float)1e32 )
973 Flow = (float)1e32;
974 else
975 {
976 Flow += AddOn;
977 if ( Flow > (float)1e32 )
978 Flow = (float)1e32;
979 }
980 }
981 return Flow;
982 }
983
984 /**Function*************************************************************
985
986 Synopsis [Computes area flow.]
987
988 Description []
989
990 SideEffects []
991
992 SeeAlso []
993
994 ***********************************************************************/
If_CutPowerFlow(If_Man_t * p,If_Cut_t * pCut,If_Obj_t * pRoot)995 float If_CutPowerFlow( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
996 {
997 If_Obj_t * pLeaf;
998 float * pSwitching = (float *)p->vSwitching->pArray;
999 float Power = 0;
1000 int i;
1001 If_CutForEachLeaf( p, pCut, pLeaf, i )
1002 {
1003 Power += pSwitching[pLeaf->Id];
1004 if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
1005 Power += If_ObjCutBest(pLeaf)->Power;
1006 else
1007 {
1008 assert( pLeaf->EstRefs > p->fEpsilon );
1009 Power += If_ObjCutBest(pLeaf)->Power / pLeaf->EstRefs;
1010 }
1011 }
1012 return Power;
1013 }
1014
1015 /**Function*************************************************************
1016
1017 Synopsis [Average number of references of the leaves.]
1018
1019 Description []
1020
1021 SideEffects []
1022
1023 SeeAlso []
1024
1025 ***********************************************************************/
If_CutAverageRefs(If_Man_t * p,If_Cut_t * pCut)1026 float If_CutAverageRefs( If_Man_t * p, If_Cut_t * pCut )
1027 {
1028 If_Obj_t * pLeaf;
1029 int nRefsTotal, i;
1030 nRefsTotal = 0;
1031 If_CutForEachLeaf( p, pCut, pLeaf, i )
1032 nRefsTotal += pLeaf->nRefs;
1033 return ((float)nRefsTotal)/pCut->nLeaves;
1034 }
1035
1036
1037 /**Function*************************************************************
1038
1039 Synopsis [Computes area of the first level.]
1040
1041 Description [The cut need to be derefed.]
1042
1043 SideEffects []
1044
1045 SeeAlso []
1046
1047 ***********************************************************************/
If_CutAreaDeref(If_Man_t * p,If_Cut_t * pCut)1048 float If_CutAreaDeref( If_Man_t * p, If_Cut_t * pCut )
1049 {
1050 If_Obj_t * pLeaf;
1051 float Area;
1052 int i;
1053 Area = If_CutLutArea(p, pCut);
1054 If_CutForEachLeaf( p, pCut, pLeaf, i )
1055 {
1056 assert( pLeaf->nRefs > 0 );
1057 if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) )
1058 continue;
1059 Area += If_CutAreaDeref( p, If_ObjCutBest(pLeaf) );
1060 }
1061 return Area;
1062 }
1063
1064 /**Function*************************************************************
1065
1066 Synopsis [Computes area of the first level.]
1067
1068 Description [The cut need to be derefed.]
1069
1070 SideEffects []
1071
1072 SeeAlso []
1073
1074 ***********************************************************************/
If_CutAreaRef(If_Man_t * p,If_Cut_t * pCut)1075 float If_CutAreaRef( If_Man_t * p, If_Cut_t * pCut )
1076 {
1077 If_Obj_t * pLeaf;
1078 float Area;
1079 int i;
1080 Area = If_CutLutArea(p, pCut);
1081 If_CutForEachLeaf( p, pCut, pLeaf, i )
1082 {
1083 assert( pLeaf->nRefs >= 0 );
1084 if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) )
1085 continue;
1086 Area += If_CutAreaRef( p, If_ObjCutBest(pLeaf) );
1087 }
1088 return Area;
1089 }
1090
1091 /**Function*************************************************************
1092
1093 Synopsis [Computes area of the first level.]
1094
1095 Description [The cut need to be derefed.]
1096
1097 SideEffects []
1098
1099 SeeAlso []
1100
1101 ***********************************************************************/
If_CutAreaDerefed(If_Man_t * p,If_Cut_t * pCut)1102 float If_CutAreaDerefed( If_Man_t * p, If_Cut_t * pCut )
1103 {
1104 float aResult, aResult2;
1105 if ( pCut->nLeaves < 2 )
1106 return 0;
1107 aResult2 = If_CutAreaRef( p, pCut );
1108 aResult = If_CutAreaDeref( p, pCut );
1109 assert( aResult > aResult2 - 3*p->fEpsilon );
1110 assert( aResult < aResult2 + 3*p->fEpsilon );
1111 return aResult;
1112 }
1113
1114 /**Function*************************************************************
1115
1116 Synopsis [Computes area of the first level.]
1117
1118 Description [The cut need to be derefed.]
1119
1120 SideEffects []
1121
1122 SeeAlso []
1123
1124 ***********************************************************************/
If_CutAreaRefed(If_Man_t * p,If_Cut_t * pCut)1125 float If_CutAreaRefed( If_Man_t * p, If_Cut_t * pCut )
1126 {
1127 float aResult, aResult2;
1128 if ( pCut->nLeaves < 2 )
1129 return 0;
1130 aResult2 = If_CutAreaDeref( p, pCut );
1131 aResult = If_CutAreaRef( p, pCut );
1132 assert( aResult > aResult2 - p->fEpsilon );
1133 assert( aResult < aResult2 + p->fEpsilon );
1134 return aResult;
1135 }
1136
1137
1138 /**Function*************************************************************
1139
1140 Synopsis [Computes area of the first level.]
1141
1142 Description [The cut need to be derefed.]
1143
1144 SideEffects []
1145
1146 SeeAlso []
1147
1148 ***********************************************************************/
If_CutEdgeDeref(If_Man_t * p,If_Cut_t * pCut)1149 float If_CutEdgeDeref( If_Man_t * p, If_Cut_t * pCut )
1150 {
1151 If_Obj_t * pLeaf;
1152 float Edge;
1153 int i;
1154 Edge = pCut->nLeaves;
1155 If_CutForEachLeaf( p, pCut, pLeaf, i )
1156 {
1157 assert( pLeaf->nRefs > 0 );
1158 if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) )
1159 continue;
1160 Edge += If_CutEdgeDeref( p, If_ObjCutBest(pLeaf) );
1161 }
1162 return Edge;
1163 }
1164
1165 /**Function*************************************************************
1166
1167 Synopsis [Computes area of the first level.]
1168
1169 Description [The cut need to be derefed.]
1170
1171 SideEffects []
1172
1173 SeeAlso []
1174
1175 ***********************************************************************/
If_CutEdgeRef(If_Man_t * p,If_Cut_t * pCut)1176 float If_CutEdgeRef( If_Man_t * p, If_Cut_t * pCut )
1177 {
1178 If_Obj_t * pLeaf;
1179 float Edge;
1180 int i;
1181 Edge = pCut->nLeaves;
1182 If_CutForEachLeaf( p, pCut, pLeaf, i )
1183 {
1184 assert( pLeaf->nRefs >= 0 );
1185 if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) )
1186 continue;
1187 Edge += If_CutEdgeRef( p, If_ObjCutBest(pLeaf) );
1188 }
1189 return Edge;
1190 }
1191
1192 /**Function*************************************************************
1193
1194 Synopsis [Computes edge of the first level.]
1195
1196 Description [The cut need to be derefed.]
1197
1198 SideEffects []
1199
1200 SeeAlso []
1201
1202 ***********************************************************************/
If_CutEdgeDerefed(If_Man_t * p,If_Cut_t * pCut)1203 float If_CutEdgeDerefed( If_Man_t * p, If_Cut_t * pCut )
1204 {
1205 float aResult, aResult2;
1206 if ( pCut->nLeaves < 2 )
1207 return pCut->nLeaves;
1208 aResult2 = If_CutEdgeRef( p, pCut );
1209 aResult = If_CutEdgeDeref( p, pCut );
1210 assert( aResult > aResult2 - 3*p->fEpsilon );
1211 assert( aResult < aResult2 + 3*p->fEpsilon );
1212 return aResult;
1213 }
1214
1215 /**Function*************************************************************
1216
1217 Synopsis [Computes area of the first level.]
1218
1219 Description [The cut need to be derefed.]
1220
1221 SideEffects []
1222
1223 SeeAlso []
1224
1225 ***********************************************************************/
If_CutEdgeRefed(If_Man_t * p,If_Cut_t * pCut)1226 float If_CutEdgeRefed( If_Man_t * p, If_Cut_t * pCut )
1227 {
1228 float aResult, aResult2;
1229 if ( pCut->nLeaves < 2 )
1230 return pCut->nLeaves;
1231 aResult2 = If_CutEdgeDeref( p, pCut );
1232 aResult = If_CutEdgeRef( p, pCut );
1233 assert( aResult > aResult2 - p->fEpsilon );
1234 assert( aResult < aResult2 + p->fEpsilon );
1235 return aResult;
1236 }
1237
1238
1239 /**Function*************************************************************
1240
1241 Synopsis [Computes area of the first level.]
1242
1243 Description [The cut need to be derefed.]
1244
1245 SideEffects []
1246
1247 SeeAlso []
1248
1249 ***********************************************************************/
If_CutPowerDeref(If_Man_t * p,If_Cut_t * pCut,If_Obj_t * pRoot)1250 float If_CutPowerDeref( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
1251 {
1252 If_Obj_t * pLeaf;
1253 float * pSwitching = (float *)p->vSwitching->pArray;
1254 float Power = 0;
1255 int i;
1256 If_CutForEachLeaf( p, pCut, pLeaf, i )
1257 {
1258 Power += pSwitching[pLeaf->Id];
1259 assert( pLeaf->nRefs > 0 );
1260 if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) )
1261 continue;
1262 Power += If_CutPowerDeref( p, If_ObjCutBest(pLeaf), pRoot );
1263 }
1264 return Power;
1265 }
1266
1267 /**Function*************************************************************
1268
1269 Synopsis [Computes area of the first level.]
1270
1271 Description [The cut need to be derefed.]
1272
1273 SideEffects []
1274
1275 SeeAlso []
1276
1277 ***********************************************************************/
If_CutPowerRef(If_Man_t * p,If_Cut_t * pCut,If_Obj_t * pRoot)1278 float If_CutPowerRef( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
1279 {
1280 If_Obj_t * pLeaf;
1281 float * pSwitching = (float *)p->vSwitching->pArray;
1282 float Power = 0;
1283 int i;
1284 If_CutForEachLeaf( p, pCut, pLeaf, i )
1285 {
1286 Power += pSwitching[pLeaf->Id];
1287 assert( pLeaf->nRefs >= 0 );
1288 if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) )
1289 continue;
1290 Power += If_CutPowerRef( p, If_ObjCutBest(pLeaf), pRoot );
1291 }
1292 return Power;
1293 }
1294
1295 /**Function*************************************************************
1296
1297 Synopsis [Computes Power of the first level.]
1298
1299 Description [The cut need to be derefed.]
1300
1301 SideEffects []
1302
1303 SeeAlso []
1304
1305 ***********************************************************************/
If_CutPowerDerefed(If_Man_t * p,If_Cut_t * pCut,If_Obj_t * pRoot)1306 float If_CutPowerDerefed( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
1307 {
1308 float aResult, aResult2;
1309 if ( pCut->nLeaves < 2 )
1310 return 0;
1311 aResult2 = If_CutPowerRef( p, pCut, pRoot );
1312 aResult = If_CutPowerDeref( p, pCut, pRoot );
1313 assert( aResult > aResult2 - p->fEpsilon );
1314 assert( aResult < aResult2 + p->fEpsilon );
1315 return aResult;
1316 }
1317
1318 /**Function*************************************************************
1319
1320 Synopsis [Computes area of the first level.]
1321
1322 Description [The cut need to be derefed.]
1323
1324 SideEffects []
1325
1326 SeeAlso []
1327
1328 ***********************************************************************/
If_CutPowerRefed(If_Man_t * p,If_Cut_t * pCut,If_Obj_t * pRoot)1329 float If_CutPowerRefed( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
1330 {
1331 float aResult, aResult2;
1332 if ( pCut->nLeaves < 2 )
1333 return 0;
1334 aResult2 = If_CutPowerDeref( p, pCut, pRoot );
1335 aResult = If_CutPowerRef( p, pCut, pRoot );
1336 assert( aResult > aResult2 - p->fEpsilon );
1337 assert( aResult < aResult2 + p->fEpsilon );
1338 return aResult;
1339 }
1340
1341 /**Function*************************************************************
1342
1343 Synopsis [Computes the cone of the cut in AIG with choices.]
1344
1345 Description []
1346
1347 SideEffects []
1348
1349 SeeAlso []
1350
1351 ***********************************************************************/
If_CutGetCutMinLevel(If_Man_t * p,If_Cut_t * pCut)1352 int If_CutGetCutMinLevel( If_Man_t * p, If_Cut_t * pCut )
1353 {
1354 If_Obj_t * pLeaf;
1355 int i, nMinLevel = IF_INFINITY;
1356 If_CutForEachLeaf( p, pCut, pLeaf, i )
1357 nMinLevel = IF_MIN( nMinLevel, (int)pLeaf->Level );
1358 return nMinLevel;
1359 }
1360
1361 /**Function*************************************************************
1362
1363 Synopsis [Computes the cone of the cut in AIG with choices.]
1364
1365 Description []
1366
1367 SideEffects []
1368
1369 SeeAlso []
1370
1371 ***********************************************************************/
If_CutGetCone_rec(If_Man_t * p,If_Obj_t * pObj,If_Cut_t * pCut)1372 int If_CutGetCone_rec( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut )
1373 {
1374 If_Obj_t * pTemp;
1375 int i, RetValue;
1376 // check if the node is in the cut
1377 for ( i = 0; i < (int)pCut->nLeaves; i++ )
1378 if ( pCut->pLeaves[i] == pObj->Id )
1379 return 1;
1380 else if ( pCut->pLeaves[i] > pObj->Id )
1381 break;
1382 // return if we reached the boundary
1383 if ( If_ObjIsCi(pObj) )
1384 return 0;
1385 // check the choice node
1386 for ( pTemp = pObj; pTemp; pTemp = pTemp->pEquiv )
1387 {
1388 // check if the node itself is bound
1389 RetValue = If_CutGetCone_rec( p, If_ObjFanin0(pTemp), pCut );
1390 if ( RetValue )
1391 RetValue &= If_CutGetCone_rec( p, If_ObjFanin1(pTemp), pCut );
1392 if ( RetValue )
1393 return 1;
1394 }
1395 return 0;
1396 }
1397
1398 /**Function*************************************************************
1399
1400 Synopsis [Computes the cone of the cut in AIG with choices.]
1401
1402 Description []
1403
1404 SideEffects []
1405
1406 SeeAlso []
1407
1408 ***********************************************************************/
If_CutGetCones(If_Man_t * p)1409 int If_CutGetCones( If_Man_t * p )
1410 {
1411 If_Obj_t * pObj;
1412 int i, Counter = 0;
1413 abctime clk = Abc_Clock();
1414 If_ManForEachObj( p, pObj, i )
1415 {
1416 if ( If_ObjIsAnd(pObj) && pObj->nRefs )
1417 {
1418 Counter += !If_CutGetCone_rec( p, pObj, If_ObjCutBest(pObj) );
1419 // Abc_Print( 1, "%d ", If_CutGetCutMinLevel( p, If_ObjCutBest(pObj) ) );
1420 }
1421 }
1422 Abc_Print( 1, "Cound not find boundary for %d nodes.\n", Counter );
1423 Abc_PrintTime( 1, "Cones", Abc_Clock() - clk );
1424 return 1;
1425 }
1426
1427
1428 /**Function*************************************************************
1429
1430 Synopsis [Computes the cone of the cut in AIG with choices.]
1431
1432 Description []
1433
1434 SideEffects []
1435
1436 SeeAlso []
1437
1438 ***********************************************************************/
If_CutFoundFanins_rec(If_Obj_t * pObj,Vec_Int_t * vLeaves)1439 void If_CutFoundFanins_rec( If_Obj_t * pObj, Vec_Int_t * vLeaves )
1440 {
1441 if ( pObj->nRefs || If_ObjIsCi(pObj) )
1442 {
1443 Vec_IntPushUnique( vLeaves, pObj->Id );
1444 return;
1445 }
1446 If_CutFoundFanins_rec( If_ObjFanin0(pObj), vLeaves );
1447 If_CutFoundFanins_rec( If_ObjFanin1(pObj), vLeaves );
1448 }
1449
1450 /**Function*************************************************************
1451
1452 Synopsis [Computes the cone of the cut in AIG with choices.]
1453
1454 Description []
1455
1456 SideEffects []
1457
1458 SeeAlso []
1459
1460 ***********************************************************************/
If_CutCountTotalFanins(If_Man_t * p)1461 int If_CutCountTotalFanins( If_Man_t * p )
1462 {
1463 If_Obj_t * pObj;
1464 Vec_Int_t * vLeaves;
1465 int i, nFaninsTotal = 0, Counter = 0;
1466 abctime clk = Abc_Clock();
1467 vLeaves = Vec_IntAlloc( 100 );
1468 If_ManForEachObj( p, pObj, i )
1469 {
1470 if ( If_ObjIsAnd(pObj) && pObj->nRefs )
1471 {
1472 nFaninsTotal += If_ObjCutBest(pObj)->nLeaves;
1473 Vec_IntClear( vLeaves );
1474 If_CutFoundFanins_rec( If_ObjFanin0(pObj), vLeaves );
1475 If_CutFoundFanins_rec( If_ObjFanin1(pObj), vLeaves );
1476 Counter += Vec_IntSize(vLeaves);
1477 }
1478 }
1479 Abc_Print( 1, "Total cut inputs = %d. Total fanins incremental = %d.\n", nFaninsTotal, Counter );
1480 Abc_PrintTime( 1, "Fanins", Abc_Clock() - clk );
1481 Vec_IntFree( vLeaves );
1482 return 1;
1483 }
1484
1485 ////////////////////////////////////////////////////////////////////////
1486 /// END OF FILE ///
1487 ////////////////////////////////////////////////////////////////////////
1488
1489
1490 ABC_NAMESPACE_IMPL_END
1491
1492