abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
abcUtil.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [abcUtil.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Network and node package.]
8 
9  Synopsis [Various utilities.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - June 20, 2005.]
16 
17  Revision [$Id: abcUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "abc.h"
22 #include "base/main/main.h"
23 #include "map/mio/mio.h"
24 #include "bool/dec/dec.h"
25 #include "misc/extra/extraBdd.h"
26 #include "opt/fxu/fxu.h"
27 
29 
30 
31 ////////////////////////////////////////////////////////////////////////
32 /// DECLARATIONS ///
33 ////////////////////////////////////////////////////////////////////////
34 
35 ////////////////////////////////////////////////////////////////////////
36 /// FUNCTION DEFINITIONS ///
37 ////////////////////////////////////////////////////////////////////////
38 
39 /**Function*************************************************************
40 
41  Synopsis [Frees one attribute manager.]
42 
43  Description []
44 
45  SideEffects []
46 
47  SeeAlso []
48 
49 ***********************************************************************/
50 void * Abc_NtkAttrFree( Abc_Ntk_t * pNtk, int Attr, int fFreeMan )
51 {
52  void * pUserMan;
53  Vec_Att_t * pAttrMan;
54  pAttrMan = (Vec_Att_t *)Vec_PtrEntry( pNtk->vAttrs, Attr );
55  Vec_PtrWriteEntry( pNtk->vAttrs, Attr, NULL );
56  pUserMan = Vec_AttFree( pAttrMan, fFreeMan );
57  return pUserMan;
58 }
59 
60 /**Function*************************************************************
61 
62  Synopsis [Order CI/COs.]
63 
64  Description []
65 
66  SideEffects []
67 
68  SeeAlso []
69 
70 ***********************************************************************/
72 {
73  Abc_Obj_t * pObj, * pTerm;
74  int i, k;
75  Vec_PtrClear( pNtk->vCis );
76  Vec_PtrClear( pNtk->vCos );
77  Abc_NtkForEachPi( pNtk, pObj, i )
78  Vec_PtrPush( pNtk->vCis, pObj );
79  Abc_NtkForEachPo( pNtk, pObj, i )
80  Vec_PtrPush( pNtk->vCos, pObj );
81  Abc_NtkForEachBox( pNtk, pObj, i )
82  {
83  if ( Abc_ObjIsLatch(pObj) )
84  continue;
85  Abc_ObjForEachFanin( pObj, pTerm, k )
86  Vec_PtrPush( pNtk->vCos, pTerm );
87  Abc_ObjForEachFanout( pObj, pTerm, k )
88  Vec_PtrPush( pNtk->vCis, pTerm );
89  }
90  Abc_NtkForEachBox( pNtk, pObj, i )
91  {
92  if ( !Abc_ObjIsLatch(pObj) )
93  continue;
94  Abc_ObjForEachFanin( pObj, pTerm, k )
95  Vec_PtrPush( pNtk->vCos, pTerm );
96  Abc_ObjForEachFanout( pObj, pTerm, k )
97  Vec_PtrPush( pNtk->vCis, pTerm );
98  }
99 }
100 
101 /**Function*************************************************************
102 
103  Synopsis [Reads the number of cubes of the node.]
104 
105  Description []
106 
107  SideEffects []
108 
109  SeeAlso []
110 
111 ***********************************************************************/
113 {
114  Abc_Obj_t * pNode;
115  int i, nCubes = 0;
116  assert( Abc_NtkHasSop(pNtk) );
117  Abc_NtkForEachNode( pNtk, pNode, i )
118  {
119  if ( Abc_NodeIsConst(pNode) )
120  continue;
121  assert( pNode->pData );
122  nCubes += Abc_SopGetCubeNum( (char *)pNode->pData );
123  }
124  return nCubes;
125 }
126 
127 /**Function*************************************************************
128 
129  Synopsis [Reads the number of cubes of the node.]
130 
131  Description []
132 
133  SideEffects []
134 
135  SeeAlso []
136 
137 ***********************************************************************/
139 {
140  Abc_Obj_t * pNode;
141  int i, nCubes, nCubePairs = 0;
142  assert( Abc_NtkHasSop(pNtk) );
143  Abc_NtkForEachNode( pNtk, pNode, i )
144  {
145  if ( Abc_NodeIsConst(pNode) )
146  continue;
147  assert( pNode->pData );
148  nCubes = Abc_SopGetCubeNum( (char *)pNode->pData );
149  nCubePairs += nCubes * (nCubes - 1) / 2;
150  }
151  return nCubePairs;
152 }
153 
154 /**Function*************************************************************
155 
156  Synopsis [Reads the number of literals in the SOPs of the nodes.]
157 
158  Description []
159 
160  SideEffects []
161 
162  SeeAlso []
163 
164 ***********************************************************************/
166 {
167  Abc_Obj_t * pNode;
168  int i, nLits = 0;
169  assert( Abc_NtkHasSop(pNtk) );
170  Abc_NtkForEachNode( pNtk, pNode, i )
171  {
172  assert( pNode->pData );
173  nLits += Abc_SopGetLitNum( (char *)pNode->pData );
174  }
175  return nLits;
176 }
177 
178 /**Function*************************************************************
179 
180  Synopsis [Counts the number of literals in the factored forms.]
181 
182  Description []
183 
184  SideEffects []
185 
186  SeeAlso []
187 
188 ***********************************************************************/
190 {
191  Dec_Graph_t * pFactor;
192  Abc_Obj_t * pNode;
193  int nNodes, i;
194  assert( Abc_NtkHasSop(pNtk) );
195  nNodes = 0;
196  Abc_NtkForEachNode( pNtk, pNode, i )
197  {
198  if ( Abc_NodeIsConst(pNode) )
199  continue;
200  pFactor = Dec_Factor( (char *)pNode->pData );
201  nNodes += 1 + Dec_GraphNodeNum(pFactor);
202  Dec_GraphFree( pFactor );
203  }
204  return nNodes;
205 }
206 
207 /**Function*************************************************************
208 
209  Synopsis [Counts the number of nodes with more than 1 reference.]
210 
211  Description []
212 
213  SideEffects []
214 
215  SeeAlso []
216 
217 ***********************************************************************/
219 {
220  Abc_Obj_t * pNode;
221  int nNodes, i;
222  assert( Abc_NtkIsStrash(pNtk) );
223  nNodes = 0;
224  Abc_NtkForEachNode( pNtk, pNode, i )
225  nNodes += (int)(Abc_ObjFanoutNum(pNode) > 1);
226  return nNodes;
227 }
228 
229 /**Function*************************************************************
230 
231  Synopsis [Reads the number of BDD nodes.]
232 
233  Description []
234 
235  SideEffects []
236 
237  SeeAlso []
238 
239 ***********************************************************************/
241 {
242  Abc_Obj_t * pNode;
243  int i, nNodes = 0;
244  assert( Abc_NtkIsBddLogic(pNtk) );
245  Abc_NtkForEachNode( pNtk, pNode, i )
246  {
247  assert( pNode->pData );
248  if ( Abc_ObjFaninNum(pNode) < 2 )
249  continue;
250  nNodes += pNode->pData? -1 + Cudd_DagSize( (DdNode *)pNode->pData ) : 0;
251  }
252  return nNodes;
253 }
254 
255 /**Function*************************************************************
256 
257  Synopsis [Reads the number of BDD nodes.]
258 
259  Description []
260 
261  SideEffects []
262 
263  SeeAlso []
264 
265 ***********************************************************************/
267 {
268  Abc_Obj_t * pNode;
269  int i, nNodes = 0;
270  assert( Abc_NtkIsAigLogic(pNtk) );
271  Abc_NtkForEachNode( pNtk, pNode, i )
272  {
273  assert( pNode->pData );
274  if ( Abc_ObjFaninNum(pNode) < 2 )
275  continue;
276 //printf( "%d ", Hop_DagSize( pNode->pData ) );
277  nNodes += pNode->pData? Hop_DagSize( (Hop_Obj_t *)pNode->pData ) : 0;
278  }
279  return nNodes;
280 }
281 
282 /**Function*************************************************************
283 
284  Synopsis [Reads the number of BDD nodes.]
285 
286  Description []
287 
288  SideEffects []
289 
290  SeeAlso []
291 
292 ***********************************************************************/
294 {
295  extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover );
296  Abc_Obj_t * pNode;
297  DdNode * bCover, * zCover, * bFunc;
298  DdManager * dd = (DdManager *)pNtk->pManFunc;
299  int i, nClauses = 0;
300  assert( Abc_NtkIsBddLogic(pNtk) );
301  Abc_NtkForEachNode( pNtk, pNode, i )
302  {
303  assert( pNode->pData );
304  bFunc = (DdNode *)pNode->pData;
305 
306  bCover = Cudd_zddIsop( dd, bFunc, bFunc, &zCover );
307  Cudd_Ref( bCover );
308  Cudd_Ref( zCover );
309  nClauses += Abc_CountZddCubes( dd, zCover );
310  Cudd_RecursiveDeref( dd, bCover );
311  Cudd_RecursiveDerefZdd( dd, zCover );
312 
313  bCover = Cudd_zddIsop( dd, Cudd_Not(bFunc), Cudd_Not(bFunc), &zCover );
314  Cudd_Ref( bCover );
315  Cudd_Ref( zCover );
316  nClauses += Abc_CountZddCubes( dd, zCover );
317  Cudd_RecursiveDeref( dd, bCover );
318  Cudd_RecursiveDerefZdd( dd, zCover );
319  }
320  return nClauses;
321 }
322 
323 /**Function*************************************************************
324 
325  Synopsis [Computes the area of the mapped circuit.]
326 
327  Description []
328 
329  SideEffects []
330 
331  SeeAlso []
332 
333 ***********************************************************************/
335 {
336  Abc_Obj_t * pObj;
337  double TotalArea;
338  int i;
339  assert( Abc_NtkHasMapping(pNtk) );
340  TotalArea = 0.0;
341  Abc_NtkForEachNode( pNtk, pObj, i )
342  {
343  if ( Abc_ObjIsBarBuf(pObj) )
344  continue;
345 // assert( pObj->pData );
346  if ( pObj->pData == NULL )
347  {
348  printf( "Node without mapping is encountered.\n" );
349  continue;
350  }
351  TotalArea += Mio_GateReadArea( (Mio_Gate_t *)pObj->pData );
352  // assuming that twin gates follow each other
353  if ( Abc_NtkFetchTwinNode(pObj) )
354  i++;
355  }
356  return TotalArea;
357 }
358 
359 /**Function*************************************************************
360 
361  Synopsis [Counts the number of exors.]
362 
363  Description []
364 
365  SideEffects []
366 
367  SeeAlso []
368 
369 ***********************************************************************/
371 {
372  Abc_Obj_t * pNode;
373  int i, Counter = 0;
374  Abc_NtkForEachNode( pNtk, pNode, i )
375  Counter += pNode->fExor;
376  return Counter;
377 }
378 
379 /**Function*************************************************************
380 
381  Synopsis [Counts the number of exors.]
382 
383  Description []
384 
385  SideEffects []
386 
387  SeeAlso []
388 
389 ***********************************************************************/
391 {
392  Abc_Obj_t * pNode;
393  int i, Counter = 0;
394  Abc_NtkForEachNode( pNtk, pNode, i )
395  Counter += Abc_NodeIsMuxType(pNode);
396  return Counter;
397 }
398 
399 /**Function*************************************************************
400 
401  Synopsis [Counts the number of exors.]
402 
403  Description []
404 
405  SideEffects []
406 
407  SeeAlso []
408 
409 ***********************************************************************/
411 {
412  Abc_Obj_t * pNode;
413  int i, Counter = 0;
414  Abc_NtkForEachNode( pNtk, pNode, i )
415  Counter += (Abc_ObjFaninNum(pNode) == 1);
416  return Counter;
417 }
418 
419 /**Function*************************************************************
420 
421  Synopsis [Returns 1 if it is an AIG with choice nodes.]
422 
423  Description []
424 
425  SideEffects []
426 
427  SeeAlso []
428 
429 ***********************************************************************/
431 {
432  Abc_Obj_t * pNode;
433  int i, Counter;
434  if ( !Abc_NtkIsStrash(pNtk) )
435  return 0;
436  Counter = 0;
437  Abc_NtkForEachNode( pNtk, pNode, i )
438  Counter += Abc_AigNodeIsChoice( pNode );
439  return Counter;
440 }
441 
442 /**Function*************************************************************
443 
444  Synopsis [Reads the maximum number of fanins.]
445 
446  Description []
447 
448  SideEffects []
449 
450  SeeAlso []
451 
452 ***********************************************************************/
454 {
455  Abc_Obj_t * pNode;
456  int i, nFaninsMax = 0;
457  Abc_NtkForEachNode( pNtk, pNode, i )
458  {
459  if ( nFaninsMax < Abc_ObjFaninNum(pNode) )
460  nFaninsMax = Abc_ObjFaninNum(pNode);
461  }
462  return nFaninsMax;
463 }
465 {
466  Abc_Obj_t * pNode;
467  int i, nFaninsMax = 0;
468  Abc_NtkForEachNode( pNtk, pNode, i )
469  {
470  if ( nFaninsMax < Abc_ObjFanoutNum(pNode) )
471  nFaninsMax = Abc_ObjFanoutNum(pNode);
472  }
473  return nFaninsMax;
474 }
475 
476 /**Function*************************************************************
477 
478  Synopsis [Reads the total number of all fanins.]
479 
480  Description []
481 
482  SideEffects []
483 
484  SeeAlso []
485 
486 ***********************************************************************/
488 {
489  Abc_Obj_t * pNode;
490  int i, nFanins = 0;
491  Abc_NtkForEachNode( pNtk, pNode, i )
492  nFanins += Abc_ObjFaninNum(pNode);
493  return nFanins;
494 }
495 
496 /**Function*************************************************************
497 
498  Synopsis [Cleans the copy field of all objects.]
499 
500  Description []
501 
502  SideEffects []
503 
504  SeeAlso []
505 
506 ***********************************************************************/
508 {
509  Abc_Obj_t * pObj;
510  int i;
511  Abc_NtkForEachObj( pNtk, pObj, i )
512  pObj->pCopy = NULL;
513 }
515 {
516  Abc_Obj_t * pObj;
517  int i;
518  Abc_NtkCleanCopy( pNtk );
519  Abc_NtkForEachBox( pNtk, pObj, i )
521 }
522 
523 /**Function*************************************************************
524 
525  Synopsis [Cleans the copy field of all objects.]
526 
527  Description []
528 
529  SideEffects []
530 
531  SeeAlso []
532 
533 ***********************************************************************/
535 {
536  Abc_Obj_t * pObj;
537  int i;
538  Abc_NtkForEachObj( pNtk, pObj, i )
539  pObj->pData = NULL;
540 }
541 
542 /**Function*************************************************************
543 
544  Synopsis [Cleans the copy field of all objects.]
545 
546  Description []
547 
548  SideEffects []
549 
550  SeeAlso []
551 
552 ***********************************************************************/
554 {
555  Abc_Obj_t * pObj;
556  int i;
557  Abc_NtkForEachObj( pNtk, pObj, i )
558  pObj->iTemp = -1;
559 }
560 
561 /**Function*************************************************************
562 
563  Synopsis [Counts the number of nodes having non-trivial copies.]
564 
565  Description []
566 
567  SideEffects []
568 
569  SeeAlso []
570 
571 ***********************************************************************/
573 {
574  Abc_Obj_t * pObj;
575  int i, Counter = 0;
576  Abc_NtkForEachObj( pNtk, pObj, i )
577  {
578  if ( Abc_ObjIsNode(pObj) )
579  Counter += (pObj->pCopy != NULL);
580  }
581  return Counter;
582 }
583 
584 /**Function*************************************************************
585 
586  Synopsis [Saves copy field of the objects.]
587 
588  Description []
589 
590  SideEffects []
591 
592  SeeAlso []
593 
594 ***********************************************************************/
596 {
597  Vec_Ptr_t * vCopies;
598  Abc_Obj_t * pObj;
599  int i;
600  vCopies = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) );
601  Abc_NtkForEachObj( pNtk, pObj, i )
602  Vec_PtrWriteEntry( vCopies, i, pObj->pCopy );
603  return vCopies;
604 }
605 
606 /**Function*************************************************************
607 
608  Synopsis [Loads copy field of the objects.]
609 
610  Description []
611 
612  SideEffects []
613 
614  SeeAlso []
615 
616 ***********************************************************************/
617 void Abc_NtkLoadCopy( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCopies )
618 {
619  Abc_Obj_t * pObj;
620  int i;
621  Abc_NtkForEachObj( pNtk, pObj, i )
622  pObj->pCopy = (Abc_Obj_t *)Vec_PtrEntry( vCopies, i );
623 }
624 
625 /**Function*************************************************************
626 
627  Synopsis [Cleans the copy field of all objects.]
628 
629  Description []
630 
631  SideEffects []
632 
633  SeeAlso []
634 
635 ***********************************************************************/
637 {
638  Abc_Obj_t * pObj;
639  int i;
640  Abc_NtkForEachObj( pNtk, pObj, i )
641  pObj->pNext = NULL;
642 }
644 {
645  Abc_Obj_t * pObj;
646  int i;
647  Abc_NtkCleanNext( pNtk );
648  Abc_NtkForEachBox( pNtk, pObj, i )
650 }
651 
652 /**Function*************************************************************
653 
654  Synopsis [Cleans the copy field of all objects.]
655 
656  Description []
657 
658  SideEffects []
659 
660  SeeAlso []
661 
662 ***********************************************************************/
664 {
665  Abc_Obj_t * pObj;
666  int i;
667  Abc_NtkForEachObj( pNtk, pObj, i )
668  pObj->fMarkA = 0;
669 }
670 
671 /**Function*************************************************************
672 
673  Synopsis [Cleans the copy field of all objects.]
674 
675  Description []
676 
677  SideEffects []
678 
679  SeeAlso []
680 
681 ***********************************************************************/
683 {
684  Abc_Obj_t * pObj;
685  int i;
686  Abc_NtkForEachObj( pNtk, pObj, i )
687  pObj->fMarkB = 0;
688 }
689 
690 /**Function*************************************************************
691 
692  Synopsis [Cleans the copy field of all objects.]
693 
694  Description []
695 
696  SideEffects []
697 
698  SeeAlso []
699 
700 ***********************************************************************/
702 {
703  Abc_Obj_t * pObj;
704  int i;
705  Abc_NtkForEachObj( pNtk, pObj, i )
706  pObj->fMarkC = 0;
707 }
708 
709 /**Function*************************************************************
710 
711  Synopsis [Cleans the copy field of all objects.]
712 
713  Description []
714 
715  SideEffects []
716 
717  SeeAlso []
718 
719 ***********************************************************************/
721 {
722  Abc_Obj_t * pObj;
723  int i;
724  Abc_NtkForEachObj( pNtk, pObj, i )
725  pObj->fMarkA = pObj->fMarkB = 0;
726 }
727 
728 /**Function*************************************************************
729 
730  Synopsis [Cleans the copy field of all objects.]
731 
732  Description []
733 
734  SideEffects []
735 
736  SeeAlso []
737 
738 ***********************************************************************/
740 {
741  Abc_Obj_t * pObj;
742  int i;
743  Abc_NtkForEachObj( pNtk, pObj, i )
744  pObj->fMarkA = pObj->fMarkB = pObj->fMarkC = 0;
745 }
746 
747 /**Function*************************************************************
748 
749  Synopsis [Returns the index of the given fanin.]
750 
751  Description []
752 
753  SideEffects []
754 
755  SeeAlso []
756 
757 ***********************************************************************/
758 int Abc_NodeFindFanin( Abc_Obj_t * pNode, Abc_Obj_t * pFanin )
759 {
760  Abc_Obj_t * pThis;
761  int i;
762  Abc_ObjForEachFanin( pNode, pThis, i )
763  if ( pThis == pFanin )
764  return i;
765  return -1;
766 }
767 
768 /**Function*************************************************************
769 
770  Synopsis [Checks if the internal node has CO fanout.]
771 
772  Description []
773 
774  SideEffects []
775 
776  SeeAlso []
777 
778 ***********************************************************************/
780 {
781  Abc_Obj_t * pFanout;
782  int i;
783  Abc_ObjForEachFanout( pNode, pFanout, i )
784  if ( Abc_ObjIsCo(pFanout) )
785  return pFanout;
786  return NULL;
787 }
788 
789 /**Function*************************************************************
790 
791  Synopsis [Checks if the internal node has CO fanout.]
792 
793  Description []
794 
795  SideEffects []
796 
797  SeeAlso []
798 
799 ***********************************************************************/
801 {
802  Abc_Obj_t * pFanout;
803  int i;
804  Abc_ObjForEachFanout( pNode, pFanout, i )
805  if ( !Abc_ObjIsCo(pFanout) )
806  return pFanout;
807  return NULL;
808 }
809 
810 /**Function*************************************************************
811 
812  Synopsis [Checks if the internal node has CO drivers with the same name.]
813 
814  Description [Checks if the internal node can borrow its name from CO fanouts.
815  This is possible if all COs with non-complemented fanin edge pointing to this
816  node have the same name.]
817 
818  SideEffects []
819 
820  SeeAlso []
821 
822 ***********************************************************************/
824 {
825  Abc_Obj_t * pFanout, * pFanoutCo;
826  int i;
827  pFanoutCo = NULL;
828  Abc_ObjForEachFanout( pNode, pFanout, i )
829  {
830  if ( !Abc_ObjIsCo(pFanout) )
831  continue;
832  if ( Abc_ObjFaninC0(pFanout) )
833  continue;
834  if ( pFanoutCo == NULL )
835  {
836  assert( Abc_ObjFaninNum(pFanout) == 1 );
837  assert( Abc_ObjFanin0(pFanout) == pNode );
838  pFanoutCo = pFanout;
839  continue;
840  }
841  if ( strcmp( Abc_ObjName(pFanoutCo), Abc_ObjName(pFanout) ) ) // they have diff names
842  return NULL;
843  }
844  return pFanoutCo;
845 }
846 
847 /**Function*************************************************************
848 
849  Synopsis [Fixes the CO driver problem.]
850 
851  Description []
852 
853  SideEffects []
854 
855  SeeAlso []
856 
857 ***********************************************************************/
858 void Abc_NtkFixCoDriverProblem( Abc_Obj_t * pDriver, Abc_Obj_t * pNodeCo, int fDuplicate )
859 {
860  Abc_Ntk_t * pNtk = pDriver->pNtk;
861  Abc_Obj_t * pDriverNew, * pFanin;
862  int k;
863  if ( fDuplicate && !Abc_ObjIsCi(pDriver) )
864  {
865  pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
866  Abc_ObjForEachFanin( pDriver, pFanin, k )
867  Abc_ObjAddFanin( pDriverNew, pFanin );
868  if ( Abc_ObjFaninC0(pNodeCo) )
869  {
870  // change polarity of the duplicated driver
871  Abc_NodeComplement( pDriverNew );
872  Abc_ObjXorFaninC( pNodeCo, 0 );
873  }
874  }
875  else
876  {
877  // add inverters and buffers when necessary
878  if ( Abc_ObjFaninC0(pNodeCo) )
879  {
880  pDriverNew = Abc_NtkCreateNodeInv( pNtk, pDriver );
881  Abc_ObjXorFaninC( pNodeCo, 0 );
882  }
883  else
884  pDriverNew = Abc_NtkCreateNodeBuf( pNtk, pDriver );
885  }
886  // update the fanin of the PO node
887  Abc_ObjPatchFanin( pNodeCo, pDriver, pDriverNew );
888  assert( Abc_ObjFanoutNum(pDriverNew) == 1 );
889  // remove the old driver if it dangles
890  // (this happens when the duplicated driver had only one complemented fanout)
891  if ( Abc_ObjFanoutNum(pDriver) == 0 )
892  Abc_NtkDeleteObj( pDriver );
893 }
894 
895 /**Function*************************************************************
896 
897  Synopsis [Returns 1 if COs of a logic network are simple.]
898 
899  Description [The COs of a logic network are simple under three conditions:
900  (1) The edge from CO to its driver is not complemented.
901  (2) If CI is a driver of a CO, they have the same name.]
902  (3) If two COs share the same driver, they have the same name.]
903 
904  SideEffects []
905 
906  SeeAlso []
907 
908 ***********************************************************************/
910 {
911  Abc_Obj_t * pNode, * pDriver;
912  int i;
913  assert( Abc_NtkIsLogic(pNtk) );
914  Abc_NtkIncrementTravId( pNtk );
915  Abc_NtkForEachCo( pNtk, pNode, i )
916  {
917  // if the driver is complemented, this is an error
918  pDriver = Abc_ObjFanin0(pNode);
919  if ( Abc_ObjFaninC0(pNode) )
920  return 0;
921  // if the driver is a CI and has different name, this is an error
922  if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
923  return 0;
924  // if the driver is visited for the first time, remember the CO name
925  if ( !Abc_NodeIsTravIdCurrent(pDriver) )
926  {
927  pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
928  Abc_NodeSetTravIdCurrent(pDriver);
929  continue;
930  }
931  // the driver has second CO - if they have different name, this is an error
932  if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
933  return 0;
934  }
935  return 1;
936 }
937 
938 /**Function*************************************************************
939 
940  Synopsis [Transforms the network to have simple COs.]
941 
942  Description [The COs of a logic network are simple under three conditions:
943  (1) The edge from CO to its driver is not complemented.
944  (2) If CI is a driver of a CO, they have the same name.]
945  (3) If two COs share the same driver, they have the same name.
946  In some cases, such as FPGA mapping, we prevent the increase in delay
947  by duplicating the driver nodes, rather than adding invs/bufs.]
948 
949  SideEffects []
950 
951  SeeAlso []
952 
953 ***********************************************************************/
954 int Abc_NtkLogicMakeSimpleCos2( Abc_Ntk_t * pNtk, int fDuplicate )
955 {
956  Abc_Obj_t * pNode, * pDriver;
957  int i, nDupGates = 0;
958  assert( Abc_NtkIsLogic(pNtk) );
959  Abc_NtkIncrementTravId( pNtk );
960  Abc_NtkForEachCo( pNtk, pNode, i )
961  {
962  // if the driver is complemented, this is an error
963  pDriver = Abc_ObjFanin0(pNode);
964  if ( Abc_ObjFaninC0(pNode) )
965  {
966  Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
967  nDupGates++;
968  continue;
969  }
970  // if the driver is a CI and has different name, this is an error
971  if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
972  {
973  Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
974  nDupGates++;
975  continue;
976  }
977  // if the driver is visited for the first time, remember the CO name
978  if ( !Abc_NodeIsTravIdCurrent(pDriver) )
979  {
980  pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
981  Abc_NodeSetTravIdCurrent(pDriver);
982  continue;
983  }
984  // the driver has second CO - if they have different name, this is an error
985  if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
986  {
987  Abc_NtkFixCoDriverProblem( pDriver, pNode, fDuplicate );
988  nDupGates++;
989  continue;
990  }
991  }
993  return nDupGates;
994 }
995 
996 
997 /**Function*************************************************************
998 
999  Synopsis [Transforms the network to have simple COs.]
1000 
1001  Description []
1002 
1003  SideEffects []
1004 
1005  SeeAlso []
1006 
1007 ***********************************************************************/
1008 void Abc_NtkLogicMakeSimpleCosTest( Abc_Ntk_t * pNtk, int fDuplicate )
1009 {
1010  int nObjs = Abc_NtkObjNumMax(pNtk);
1011  unsigned * pType = ABC_CALLOC( unsigned, nObjs );
1012  Abc_Obj_t * pNode;
1013  int i, Counts[4] = {0}, Consts[2] = {0}, Inputs[2] = {0};
1014  // collect info
1015  Abc_NtkForEachCo( pNtk, pNode, i )
1016  {
1017  if ( Abc_ObjFaninId0(pNode) == 0 )
1018  Consts[Abc_ObjFaninC0(pNode)]++;
1019  if ( Abc_ObjIsCi(Abc_ObjFanin0(pNode)) )
1020  Inputs[Abc_ObjFaninC0(pNode)]++;
1021  pType[Abc_ObjFaninId0(pNode)] |= (1 << Abc_ObjFaninC0(pNode));
1022  }
1023  // count the numbers
1024  for ( i = 0; i < nObjs; i++ )
1025  Counts[pType[i]]++;
1026  for ( i = 0; i < 4; i++ )
1027  printf( "%d = %d ", i, Counts[i] );
1028  for ( i = 0; i < 2; i++ )
1029  printf( "c%d = %d ", i, Consts[i] );
1030  for ( i = 0; i < 2; i++ )
1031  printf( "i%d = %d ", i, Inputs[i] );
1032  printf( "\n" );
1033  ABC_FREE( pType );
1034 }
1035 
1036 /**Function*************************************************************
1037 
1038  Synopsis [Transforms the network to have simple COs.]
1039 
1040  Description []
1041 
1042  SideEffects []
1043 
1044  SeeAlso []
1045 
1046 ***********************************************************************/
1047 int Abc_NtkLogicMakeSimpleCos( Abc_Ntk_t * pNtk, int fDuplicate )
1048 {
1049  Vec_Ptr_t * vDrivers, * vCoTerms;
1050  Abc_Obj_t * pNode, * pDriver, * pDriverNew, * pFanin;
1051  int i, k, LevelMax, nTotal = 0;
1052  assert( Abc_NtkIsLogic(pNtk) );
1053  LevelMax = Abc_NtkLevel(pNtk);
1054 // Abc_NtkLogicMakeSimpleCosTest( pNtk, fDuplicate );
1055 
1056  // fix constant drivers
1057  Abc_NtkForEachCo( pNtk, pNode, i )
1058  {
1059  pDriver = Abc_ObjFanin0(pNode);
1060  if ( !Abc_NodeIsConst(pDriver) )
1061  continue;
1062  pDriverNew = (Abc_ObjFaninC0(pNode) == Abc_NodeIsConst0(pDriver)) ? Abc_NtkCreateNodeConst1(pNtk) : Abc_NtkCreateNodeConst0(pNtk);
1063  if ( Abc_ObjFaninC0(pNode) )
1064  Abc_ObjXorFaninC( pNode, 0 );
1065  Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
1066  if ( Abc_ObjFanoutNum(pDriver) == 0 )
1067  Abc_NtkDeleteObj( pDriver );
1068  }
1069 
1070  // collect drivers pointed by complemented edges
1071  vDrivers = Vec_PtrAlloc( 100 );
1072  Abc_NtkIncrementTravId( pNtk );
1073  Abc_NtkForEachCo( pNtk, pNode, i )
1074  {
1075  if ( !Abc_ObjFaninC0(pNode) )
1076  continue;
1077  pDriver = Abc_ObjFanin0(pNode);
1078  if ( Abc_NodeIsTravIdCurrent(pDriver) )
1079  continue;
1080  Abc_NodeSetTravIdCurrent(pDriver);
1081  Vec_PtrPush( vDrivers, pDriver );
1082  }
1083  // fix complemented drivers
1084  if ( Vec_PtrSize(vDrivers) > 0 )
1085  {
1086  int nDupGates = 0, nDupInvs = 0, nDupChange = 0;
1087  Vec_Ptr_t * vFanouts = Vec_PtrAlloc( 100 );
1088  Vec_PtrForEachEntry( Abc_Obj_t *, vDrivers, pDriver, i )
1089  {
1090  int fHasDir = 0, fHasInv = 0, fHasOther = 0;
1091  Abc_ObjForEachFanout( pDriver, pNode, k )
1092  {
1093  if ( !Abc_ObjIsCo(pNode) )
1094  {
1095  assert( !Abc_ObjFaninC0(pNode) );
1096  fHasOther = 1;
1097  continue;
1098  }
1099  if ( Abc_ObjFaninC0(pNode) )
1100  fHasInv = 1;
1101  else //if ( Abc_ObjFaninC0(pNode) )
1102  fHasDir = 1;
1103  }
1104  assert( fHasInv );
1105  if ( Abc_ObjIsCi(pDriver) || fHasDir || (fHasOther && Abc_NtkHasMapping(pNtk)) ) // cannot change
1106  {
1107  // duplicate if critical
1108  if ( fDuplicate && Abc_ObjIsNode(pDriver) && Abc_ObjLevel(pDriver) == LevelMax )
1109  {
1110  pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
1111  Abc_ObjForEachFanin( pDriver, pFanin, k )
1112  Abc_ObjAddFanin( pDriverNew, pFanin );
1113  Abc_NodeComplement( pDriverNew );
1114  nDupGates++;
1115  }
1116  else // add inverter
1117  {
1118  pDriverNew = Abc_NtkCreateNodeInv( pNtk, pDriver );
1119  nDupInvs++;
1120  }
1121  // collect CO fanouts to be redirected to the new node
1122  Vec_PtrClear( vFanouts );
1123  Abc_ObjForEachFanout( pDriver, pNode, k )
1124  if ( Abc_ObjIsCo(pNode) && Abc_ObjFaninC0(pNode) )
1125  Vec_PtrPush( vFanouts, pNode );
1126  assert( Vec_PtrSize(vFanouts) > 0 );
1127  Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pNode, k )
1128  {
1129  Abc_ObjXorFaninC( pNode, 0 );
1130  Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
1131  assert( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 0 );
1132  }
1133  }
1134  else // can change
1135  {
1136  // change polarity of the driver
1137  assert( Abc_ObjIsNode(pDriver) );
1138  Abc_NodeComplement( pDriver );
1139  Abc_ObjForEachFanout( pDriver, pNode, k )
1140  {
1141  if ( Abc_ObjIsCo(pNode) )
1142  {
1143  assert( Abc_ObjFaninC0(pNode) );
1144  Abc_ObjXorFaninC( pNode, 0 );
1145  }
1146  else if ( Abc_ObjIsNode(pNode) )
1147  Abc_NodeComplementInput( pNode, pDriver );
1148  else assert( 0 );
1149  }
1150  nDupChange++;
1151  }
1152  }
1153  Vec_PtrFree( vFanouts );
1154 // printf( "Resolving inverted CO drivers: Invs = %d. Dups = %d. Changes = %d.\n",
1155 // nDupInvs, nDupGates, nDupChange );
1156  nTotal += nDupInvs + nDupGates;
1157  }
1158  Vec_PtrFree( vDrivers );
1159 
1160  // collect COs that needs fixing by adding buffers or duplicating
1161  vCoTerms = Vec_PtrAlloc( 100 );
1162  Abc_NtkIncrementTravId( pNtk );
1163  Abc_NtkForEachCo( pNtk, pNode, i )
1164  {
1165  // if the driver is a CI and has different name, this is an error
1166  pDriver = Abc_ObjFanin0(pNode);
1167  if ( Abc_ObjIsCi(pDriver) && strcmp(Abc_ObjName(pDriver), Abc_ObjName(pNode)) )
1168  {
1169  Vec_PtrPush( vCoTerms, pNode );
1170  continue;
1171  }
1172  // if the driver is visited for the first time, remember the CO name
1173  if ( !Abc_NodeIsTravIdCurrent(pDriver) )
1174  {
1175  pDriver->pNext = (Abc_Obj_t *)Abc_ObjName(pNode);
1176  Abc_NodeSetTravIdCurrent(pDriver);
1177  continue;
1178  }
1179  // the driver has second CO - if they have different name, this is an error
1180  if ( strcmp((char *)pDriver->pNext, Abc_ObjName(pNode)) ) // diff names
1181  {
1182  Vec_PtrPush( vCoTerms, pNode );
1183  continue;
1184  }
1185  }
1186  // fix duplication problem
1187  if ( Vec_PtrSize(vCoTerms) > 0 )
1188  {
1189  int nDupBufs = 0, nDupGates = 0;
1190  Vec_PtrForEachEntry( Abc_Obj_t *, vCoTerms, pNode, i )
1191  {
1192  pDriver = Abc_ObjFanin0(pNode);
1193  // duplicate if critical
1194  if ( fDuplicate && Abc_ObjIsNode(pDriver) && Abc_ObjLevel(pDriver) == LevelMax )
1195  {
1196  pDriverNew = Abc_NtkDupObj( pNtk, pDriver, 0 );
1197  Abc_ObjForEachFanin( pDriver, pFanin, k )
1198  Abc_ObjAddFanin( pDriverNew, pFanin );
1199  nDupGates++;
1200  }
1201  else // add buffer
1202  {
1203  pDriverNew = Abc_NtkCreateNodeBuf( pNtk, pDriver );
1204  nDupBufs++;
1205  }
1206  // swing the PO
1207  Abc_ObjPatchFanin( pNode, pDriver, pDriverNew );
1208  assert( Abc_ObjIsCi(pDriver) || Abc_ObjFanoutNum(pDriver) > 0 );
1209  }
1210 // printf( "Resolving shared CO drivers: Bufs = %d. Dups = %d.\n", nDupBufs, nDupGates );
1211  nTotal += nDupBufs + nDupGates;
1212  }
1213  Vec_PtrFree( vCoTerms );
1214  return nTotal;
1215 }
1216 
1217 /**Function*************************************************************
1218 
1219  Synopsis [Inserts a new node in the order by levels.]
1220 
1221  Description []
1222 
1223  SideEffects []
1224 
1225  SeeAlso []
1226 
1227 ***********************************************************************/
1229 {
1230  Abc_Obj_t * pNode1, * pNode2;
1231  int i;
1232  if ( Vec_PtrPushUnique(p, pNode) )
1233  return;
1234  // find the p of the node
1235  for ( i = p->nSize-1; i > 0; i-- )
1236  {
1237  pNode1 = (Abc_Obj_t *)p->pArray[i ];
1238  pNode2 = (Abc_Obj_t *)p->pArray[i-1];
1239  if ( Abc_ObjRegular(pNode1)->Level <= Abc_ObjRegular(pNode2)->Level )
1240  break;
1241  p->pArray[i ] = pNode2;
1242  p->pArray[i-1] = pNode1;
1243  }
1244 }
1245 
1246 
1247 
1248 /**Function*************************************************************
1249 
1250  Synopsis [Returns 1 if the node is the root of EXOR/NEXOR.]
1251 
1252  Description []
1253 
1254  SideEffects []
1255 
1256  SeeAlso []
1257 
1258 ***********************************************************************/
1260 {
1261  Abc_Obj_t * pNode0, * pNode1;
1262  // check that the node is regular
1263  assert( !Abc_ObjIsComplement(pNode) );
1264  // if the node is not AND, this is not EXOR
1265  if ( !Abc_AigNodeIsAnd(pNode) )
1266  return 0;
1267  // if the children are not complemented, this is not EXOR
1268  if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
1269  return 0;
1270  // get children
1271  pNode0 = Abc_ObjFanin0(pNode);
1272  pNode1 = Abc_ObjFanin1(pNode);
1273  // if the children are not ANDs, this is not EXOR
1274  if ( Abc_ObjFaninNum(pNode0) != 2 || Abc_ObjFaninNum(pNode1) != 2 )
1275  return 0;
1276  // this is AIG, which means the fanins should be ordered
1277  assert( Abc_ObjFaninId0(pNode0) != Abc_ObjFaninId1(pNode1) ||
1278  Abc_ObjFaninId0(pNode1) != Abc_ObjFaninId1(pNode0) );
1279  // if grand children are not the same, this is not EXOR
1280  if ( Abc_ObjFaninId0(pNode0) != Abc_ObjFaninId0(pNode1) ||
1281  Abc_ObjFaninId1(pNode0) != Abc_ObjFaninId1(pNode1) )
1282  return 0;
1283  // finally, if the complemented edges are matched, this is not EXOR
1284  if ( Abc_ObjFaninC0(pNode0) == Abc_ObjFaninC0(pNode1) ||
1285  Abc_ObjFaninC1(pNode0) == Abc_ObjFaninC1(pNode1) )
1286  return 0;
1287  return 1;
1288 }
1289 
1290 /**Function*************************************************************
1291 
1292  Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
1293 
1294  Description []
1295 
1296  SideEffects []
1297 
1298  SeeAlso []
1299 
1300 ***********************************************************************/
1302 {
1303  Abc_Obj_t * pNode0, * pNode1;
1304  // check that the node is regular
1305  assert( !Abc_ObjIsComplement(pNode) );
1306  // if the node is not AND, this is not MUX
1307  if ( !Abc_AigNodeIsAnd(pNode) )
1308  return 0;
1309  // if the children are not complemented, this is not MUX
1310  if ( !Abc_ObjFaninC0(pNode) || !Abc_ObjFaninC1(pNode) )
1311  return 0;
1312  // get children
1313  pNode0 = Abc_ObjFanin0(pNode);
1314  pNode1 = Abc_ObjFanin1(pNode);
1315  // if the children are not ANDs, this is not MUX
1316  if ( !Abc_AigNodeIsAnd(pNode0) || !Abc_AigNodeIsAnd(pNode1) )
1317  return 0;
1318  // otherwise the node is MUX iff it has a pair of equal grandchildren with opposite polarity
1319  return (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC0(pNode1))) ||
1320  (Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC1(pNode1))) ||
1321  (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC0(pNode1))) ||
1322  (Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC1(pNode1)));
1323 }
1324 
1325 /**Function*************************************************************
1326 
1327  Synopsis [Returns 1 if the node is the root of MUX or EXOR/NEXOR.]
1328 
1329  Description []
1330 
1331  SideEffects []
1332 
1333  SeeAlso []
1334 
1335 ***********************************************************************/
1337 {
1338  Abc_Obj_t * pNode;
1339  int i;
1340  int Counter = 0;
1341  Abc_NtkForEachNode( pNtk, pNode, i )
1342  Counter += Abc_NodeIsMuxType( pNode );
1343  return Counter;
1344 }
1345 
1346 /**Function*************************************************************
1347 
1348  Synopsis [Returns 1 if the node is the control type of the MUX.]
1349 
1350  Description []
1351 
1352  SideEffects []
1353 
1354  SeeAlso []
1355 
1356 ***********************************************************************/
1358 {
1359  Abc_Obj_t * pNode0, * pNode1;
1360  // check that the node is regular
1361  assert( !Abc_ObjIsComplement(pNode) );
1362  // skip the node that do not have two fanouts
1363  if ( Abc_ObjFanoutNum(pNode) != 2 )
1364  return 0;
1365  // get the fanouts
1366  pNode0 = Abc_ObjFanout( pNode, 0 );
1367  pNode1 = Abc_ObjFanout( pNode, 1 );
1368  // if they have more than one fanout, we are not interested
1369  if ( Abc_ObjFanoutNum(pNode0) != 1 || Abc_ObjFanoutNum(pNode1) != 1 )
1370  return 0;
1371  // if the fanouts have the same fanout, this is MUX or EXOR (or a redundant gate (CA)(CB))
1372  return Abc_ObjFanout0(pNode0) == Abc_ObjFanout0(pNode1);
1373 }
1374 
1375 /**Function*************************************************************
1376 
1377  Synopsis [Recognizes what nodes are control and data inputs of a MUX.]
1378 
1379  Description [If the node is a MUX, returns the control variable C.
1380  Assigns nodes T and E to be the then and else variables of the MUX.
1381  Node C is never complemented. Nodes T and E can be complemented.
1382  This function also recognizes EXOR/NEXOR gates as MUXes.]
1383 
1384  SideEffects []
1385 
1386  SeeAlso []
1387 
1388 ***********************************************************************/
1389 Abc_Obj_t * Abc_NodeRecognizeMux( Abc_Obj_t * pNode, Abc_Obj_t ** ppNodeT, Abc_Obj_t ** ppNodeE )
1390 {
1391  Abc_Obj_t * pNode0, * pNode1;
1392  assert( !Abc_ObjIsComplement(pNode) );
1393  assert( Abc_NodeIsMuxType(pNode) );
1394  // get children
1395  pNode0 = Abc_ObjFanin0(pNode);
1396  pNode1 = Abc_ObjFanin1(pNode);
1397  // find the control variable
1398 // if ( pNode1->p1 == Fraig_Not(pNode2->p1) )
1399  if ( Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC0(pNode1)) )
1400  {
1401 // if ( Fraig_IsComplement(pNode1->p1) )
1402  if ( Abc_ObjFaninC0(pNode0) )
1403  { // pNode2->p1 is positive phase of C
1404  *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
1405  *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
1406  return Abc_ObjChild0(pNode1);//pNode2->p1;
1407  }
1408  else
1409  { // pNode1->p1 is positive phase of C
1410  *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
1411  *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
1412  return Abc_ObjChild0(pNode0);//pNode1->p1;
1413  }
1414  }
1415 // else if ( pNode1->p1 == Fraig_Not(pNode2->p2) )
1416  else if ( Abc_ObjFaninId0(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC0(pNode0) ^ Abc_ObjFaninC1(pNode1)) )
1417  {
1418 // if ( Fraig_IsComplement(pNode1->p1) )
1419  if ( Abc_ObjFaninC0(pNode0) )
1420  { // pNode2->p2 is positive phase of C
1421  *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
1422  *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
1423  return Abc_ObjChild1(pNode1);//pNode2->p2;
1424  }
1425  else
1426  { // pNode1->p1 is positive phase of C
1427  *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode0));//pNode1->p2);
1428  *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
1429  return Abc_ObjChild0(pNode0);//pNode1->p1;
1430  }
1431  }
1432 // else if ( pNode1->p2 == Fraig_Not(pNode2->p1) )
1433  else if ( Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId0(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC0(pNode1)) )
1434  {
1435 // if ( Fraig_IsComplement(pNode1->p2) )
1436  if ( Abc_ObjFaninC1(pNode0) )
1437  { // pNode2->p1 is positive phase of C
1438  *ppNodeT = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
1439  *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
1440  return Abc_ObjChild0(pNode1);//pNode2->p1;
1441  }
1442  else
1443  { // pNode1->p2 is positive phase of C
1444  *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
1445  *ppNodeE = Abc_ObjNot(Abc_ObjChild1(pNode1));//pNode2->p2);
1446  return Abc_ObjChild1(pNode0);//pNode1->p2;
1447  }
1448  }
1449 // else if ( pNode1->p2 == Fraig_Not(pNode2->p2) )
1450  else if ( Abc_ObjFaninId1(pNode0) == Abc_ObjFaninId1(pNode1) && (Abc_ObjFaninC1(pNode0) ^ Abc_ObjFaninC1(pNode1)) )
1451  {
1452 // if ( Fraig_IsComplement(pNode1->p2) )
1453  if ( Abc_ObjFaninC1(pNode0) )
1454  { // pNode2->p2 is positive phase of C
1455  *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
1456  *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
1457  return Abc_ObjChild1(pNode1);//pNode2->p2;
1458  }
1459  else
1460  { // pNode1->p2 is positive phase of C
1461  *ppNodeT = Abc_ObjNot(Abc_ObjChild0(pNode0));//pNode1->p1);
1462  *ppNodeE = Abc_ObjNot(Abc_ObjChild0(pNode1));//pNode2->p1);
1463  return Abc_ObjChild1(pNode0);//pNode1->p2;
1464  }
1465  }
1466  assert( 0 ); // this is not MUX
1467  return NULL;
1468 }
1469 
1470 /**Function*************************************************************
1471 
1472  Synopsis [Prepares two network for a two-argument command similar to "verify".]
1473 
1474  Description []
1475 
1476  SideEffects []
1477 
1478  SeeAlso []
1479 
1480 ***********************************************************************/
1481 int Abc_NtkPrepareTwoNtks( FILE * pErr, Abc_Ntk_t * pNtk, char ** argv, int argc,
1482  Abc_Ntk_t ** ppNtk1, Abc_Ntk_t ** ppNtk2, int * pfDelete1, int * pfDelete2 )
1483 {
1484  int fCheck = 1;
1485  FILE * pFile;
1486  Abc_Ntk_t * pNtk1, * pNtk2, * pNtkTemp;
1487  int util_optind = 0;
1488 
1489  *pfDelete1 = 0;
1490  *pfDelete2 = 0;
1491  if ( argc == util_optind )
1492  { // use the spec
1493  if ( pNtk == NULL )
1494  {
1495  fprintf( pErr, "Empty current network.\n" );
1496  return 0;
1497  }
1498  if ( pNtk->pSpec == NULL )
1499  {
1500  fprintf( pErr, "The external spec is not given.\n" );
1501  return 0;
1502  }
1503  pFile = fopen( pNtk->pSpec, "r" );
1504  if ( pFile == NULL )
1505  {
1506  fprintf( pErr, "Cannot open the external spec file \"%s\".\n", pNtk->pSpec );
1507  return 0;
1508  }
1509  else
1510  fclose( pFile );
1511  pNtk1 = Abc_NtkDup(pNtk);
1512  pNtk2 = Io_Read( pNtk->pSpec, Io_ReadFileType(pNtk->pSpec), fCheck, 0 );
1513  if ( pNtk2 == NULL )
1514  return 0;
1515  *pfDelete1 = 1;
1516  *pfDelete2 = 1;
1517  }
1518  else if ( argc == util_optind + 1 )
1519  {
1520  if ( pNtk == NULL )
1521  {
1522  fprintf( pErr, "Empty current network.\n" );
1523  return 0;
1524  }
1525  pNtk1 = Abc_NtkDup(pNtk);
1526  pNtk2 = Io_Read( argv[util_optind], Io_ReadFileType(argv[util_optind]), fCheck, 0 );
1527  if ( pNtk2 == NULL )
1528  return 0;
1529  *pfDelete1 = 1;
1530  *pfDelete2 = 1;
1531  }
1532  else if ( argc == util_optind + 2 )
1533  {
1534  pNtk1 = Io_Read( argv[util_optind], Io_ReadFileType(argv[util_optind]), fCheck, 0 );
1535  if ( pNtk1 == NULL )
1536  return 0;
1537  pNtk2 = Io_Read( argv[util_optind+1], Io_ReadFileType(argv[util_optind+1]), fCheck, 0 );
1538  if ( pNtk2 == NULL )
1539  {
1540  Abc_NtkDelete( pNtk1 );
1541  return 0;
1542  }
1543  *pfDelete1 = 1;
1544  *pfDelete2 = 1;
1545  }
1546  else
1547  {
1548  fprintf( pErr, "Wrong number of arguments.\n" );
1549  return 0;
1550  }
1551 
1552  // make sure the networks are strashed
1553  if ( !Abc_NtkIsStrash(pNtk1) )
1554  {
1555  pNtkTemp = Abc_NtkStrash( pNtk1, 0, 1, 0 );
1556  if ( *pfDelete1 )
1557  Abc_NtkDelete( pNtk1 );
1558  pNtk1 = pNtkTemp;
1559  *pfDelete1 = 1;
1560  }
1561  if ( !Abc_NtkIsStrash(pNtk2) )
1562  {
1563  pNtkTemp = Abc_NtkStrash( pNtk2, 0, 1, 0 );
1564  if ( *pfDelete2 )
1565  Abc_NtkDelete( pNtk2 );
1566  pNtk2 = pNtkTemp;
1567  *pfDelete2 = 1;
1568  }
1569 
1570  *ppNtk1 = pNtk1;
1571  *ppNtk2 = pNtk2;
1572  return 1;
1573 }
1574 
1575 
1576 /**Function*************************************************************
1577 
1578  Synopsis [Returns 1 if it is an AIG with choice nodes.]
1579 
1580  Description []
1581 
1582  SideEffects []
1583 
1584  SeeAlso []
1585 
1586 ***********************************************************************/
1587 void Abc_NodeCollectFanins( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
1588 {
1589  Abc_Obj_t * pFanin;
1590  int i;
1591  Vec_PtrClear(vNodes);
1592  Abc_ObjForEachFanin( pNode, pFanin, i )
1593  Vec_PtrPush( vNodes, pFanin );
1594 }
1595 
1596 /**Function*************************************************************
1597 
1598  Synopsis [Returns 1 if it is an AIG with choice nodes.]
1599 
1600  Description []
1601 
1602  SideEffects []
1603 
1604  SeeAlso []
1605 
1606 ***********************************************************************/
1607 void Abc_NodeCollectFanouts( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
1608 {
1609  Abc_Obj_t * pFanout;
1610  int i;
1611  Vec_PtrClear(vNodes);
1612  Abc_ObjForEachFanout( pNode, pFanout, i )
1613  Vec_PtrPush( vNodes, pFanout );
1614 }
1615 
1616 /**Function*************************************************************
1617 
1618  Synopsis [Collects all latches in the network.]
1619 
1620  Description []
1621 
1622  SideEffects []
1623 
1624  SeeAlso []
1625 
1626 ***********************************************************************/
1628 {
1629  Vec_Ptr_t * vLatches;
1630  Abc_Obj_t * pObj;
1631  int i;
1632  vLatches = Vec_PtrAlloc( 10 );
1633  Abc_NtkForEachObj( pNtk, pObj, i )
1634  Vec_PtrPush( vLatches, pObj );
1635  return vLatches;
1636 }
1637 
1638 /**Function*************************************************************
1639 
1640  Synopsis [Procedure used for sorting the nodes in increasing order of levels.]
1641 
1642  Description []
1643 
1644  SideEffects []
1645 
1646  SeeAlso []
1647 
1648 ***********************************************************************/
1650 {
1651  int Diff = Abc_ObjRegular(*pp1)->Level - Abc_ObjRegular(*pp2)->Level;
1652  if ( Diff < 0 )
1653  return -1;
1654  if ( Diff > 0 )
1655  return 1;
1656  Diff = Abc_ObjRegular(*pp1)->Id - Abc_ObjRegular(*pp2)->Id;
1657  if ( Diff < 0 )
1658  return -1;
1659  if ( Diff > 0 )
1660  return 1;
1661  return 0;
1662 }
1663 
1664 /**Function*************************************************************
1665 
1666  Synopsis [Procedure used for sorting the nodes in decreasing order of levels.]
1667 
1668  Description []
1669 
1670  SideEffects []
1671 
1672  SeeAlso []
1673 
1674 ***********************************************************************/
1676 {
1677  int Diff = Abc_ObjRegular(*pp1)->Level - Abc_ObjRegular(*pp2)->Level;
1678  if ( Diff > 0 )
1679  return -1;
1680  if ( Diff < 0 )
1681  return 1;
1682  Diff = Abc_ObjRegular(*pp1)->Id - Abc_ObjRegular(*pp2)->Id;
1683  if ( Diff > 0 )
1684  return -1;
1685  if ( Diff < 0 )
1686  return 1;
1687  return 0;
1688 }
1689 
1690 /**Function*************************************************************
1691 
1692  Synopsis [Creates the array of fanout counters.]
1693 
1694  Description []
1695 
1696  SideEffects []
1697 
1698  SeeAlso []
1699 
1700 ***********************************************************************/
1702 {
1703  Vec_Int_t * vFanNums;
1704  Abc_Obj_t * pObj;
1705  int i;
1706  vFanNums = Vec_IntAlloc( 0 );
1707  Vec_IntFill( vFanNums, Abc_NtkObjNumMax(pNtk), -1 );
1708  Abc_NtkForEachObj( pNtk, pObj, i )
1709  if ( Abc_ObjIsCi(pObj) || Abc_ObjIsNode(pObj) )
1710  Vec_IntWriteEntry( vFanNums, i, Abc_ObjFanoutNum(pObj) );
1711  return vFanNums;
1712 }
1713 
1714 /**Function*************************************************************
1715 
1716  Synopsis [Collects all objects into one array.]
1717 
1718  Description []
1719 
1720  SideEffects []
1721 
1722  SeeAlso []
1723 
1724 ***********************************************************************/
1726 {
1727  Vec_Ptr_t * vNodes;
1728  Abc_Obj_t * pNode;
1729  int i;
1730  vNodes = Vec_PtrAlloc( 100 );
1731  Abc_NtkForEachObj( pNtk, pNode, i )
1732  Vec_PtrPush( vNodes, pNode );
1733  return vNodes;
1734 }
1735 
1736 /**Function*************************************************************
1737 
1738  Synopsis [Returns the array of CI IDs.]
1739 
1740  Description []
1741 
1742  SideEffects []
1743 
1744  SeeAlso []
1745 
1746 ***********************************************************************/
1748 {
1749  Vec_Int_t * vCiIds;
1750  Abc_Obj_t * pObj;
1751  int i;
1752  vCiIds = Vec_IntAlloc( Abc_NtkCiNum(pNtk) );
1753  Abc_NtkForEachCi( pNtk, pObj, i )
1754  Vec_IntPush( vCiIds, pObj->Id );
1755  return vCiIds;
1756 }
1757 
1758 /**Function*************************************************************
1759 
1760  Synopsis [Puts the nodes into the DFS order and reassign their IDs.]
1761 
1762  Description []
1763 
1764  SideEffects []
1765 
1766  SeeAlso []
1767 
1768 ***********************************************************************/
1770 {
1771  Vec_Ptr_t * vNodes;
1772  Vec_Ptr_t * vObjsNew;
1773  Abc_Obj_t * pNode, * pTemp, * pConst1;
1774  int i, k;
1775  assert( Abc_NtkIsStrash(pNtk) );
1776 //printf( "Total = %d. Current = %d.\n", Abc_NtkObjNumMax(pNtk), Abc_NtkObjNum(pNtk) );
1777  // start the array of objects with new IDs
1778  vObjsNew = Vec_PtrAlloc( pNtk->nObjs );
1779  // put constant node first
1780  pConst1 = Abc_AigConst1(pNtk);
1781  assert( pConst1->Id == 0 );
1782  Vec_PtrPush( vObjsNew, pConst1 );
1783  // put PI nodes next
1784  Abc_NtkForEachPi( pNtk, pNode, i )
1785  {
1786  pNode->Id = Vec_PtrSize( vObjsNew );
1787  Vec_PtrPush( vObjsNew, pNode );
1788  }
1789  // put PO nodes next
1790  Abc_NtkForEachPo( pNtk, pNode, i )
1791  {
1792  pNode->Id = Vec_PtrSize( vObjsNew );
1793  Vec_PtrPush( vObjsNew, pNode );
1794  }
1795  // put latches and their inputs/outputs next
1796  Abc_NtkForEachBox( pNtk, pNode, i )
1797  {
1798  pNode->Id = Vec_PtrSize( vObjsNew );
1799  Vec_PtrPush( vObjsNew, pNode );
1800  Abc_ObjForEachFanin( pNode, pTemp, k )
1801  {
1802  pTemp->Id = Vec_PtrSize( vObjsNew );
1803  Vec_PtrPush( vObjsNew, pTemp );
1804  }
1805  Abc_ObjForEachFanout( pNode, pTemp, k )
1806  {
1807  pTemp->Id = Vec_PtrSize( vObjsNew );
1808  Vec_PtrPush( vObjsNew, pTemp );
1809  }
1810  }
1811  // finally, internal nodes in the DFS order
1812  vNodes = Abc_AigDfs( pNtk, 1, 0 );
1813  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
1814  {
1815  if ( pNode == pConst1 )
1816  continue;
1817  pNode->Id = Vec_PtrSize( vObjsNew );
1818  Vec_PtrPush( vObjsNew, pNode );
1819  }
1820  Vec_PtrFree( vNodes );
1821  assert( Vec_PtrSize(vObjsNew) == pNtk->nObjs );
1822 
1823  // update the fanin/fanout arrays
1824  Abc_NtkForEachObj( pNtk, pNode, i )
1825  {
1826  Abc_ObjForEachFanin( pNode, pTemp, k )
1827  pNode->vFanins.pArray[k] = pTemp->Id;
1828  Abc_ObjForEachFanout( pNode, pTemp, k )
1829  pNode->vFanouts.pArray[k] = pTemp->Id;
1830  }
1831 
1832  // replace the array of objs
1833  Vec_PtrFree( pNtk->vObjs );
1834  pNtk->vObjs = vObjsNew;
1835 
1836  // rehash the AIG
1837  Abc_AigRehash( (Abc_Aig_t *)pNtk->pManFunc );
1838 
1839  // update the name manager!!!
1840 }
1841 
1842 /**Function*************************************************************
1843 
1844  Synopsis [Detect cases when non-trivial FF matching is possible.]
1845 
1846  Description []
1847 
1848  SideEffects []
1849 
1850  SeeAlso []
1851 
1852 ***********************************************************************/
1854 {
1855 /*
1856  Abc_Obj_t * pLatch, * pFanin;
1857  int i, nTFFs, nJKFFs;
1858  nTFFs = nJKFFs = 0;
1859  Abc_NtkForEachLatch( pNtk, pLatch, i )
1860  {
1861  pFanin = Abc_ObjFanin0(pLatch);
1862  if ( Abc_ObjFaninNum(pFanin) != 2 )
1863  continue;
1864  if ( Abc_NodeIsExorType(pLatch) )
1865  {
1866  if ( Abc_ObjFanin0(Abc_ObjFanin0(pFanin)) == pLatch ||
1867  Abc_ObjFanin1(Abc_ObjFanin0(pFanin)) == pLatch )
1868  nTFFs++;
1869  }
1870  if ( Abc_ObjFaninNum( Abc_ObjFanin0(pFanin) ) != 2 ||
1871  Abc_ObjFaninNum( Abc_ObjFanin1(pFanin) ) != 2 )
1872  continue;
1873 
1874  if ( (Abc_ObjFanin0(Abc_ObjFanin0(pFanin)) == pLatch ||
1875  Abc_ObjFanin1(Abc_ObjFanin0(pFanin)) == pLatch) &&
1876  (Abc_ObjFanin0(Abc_ObjFanin1(pFanin)) == pLatch ||
1877  Abc_ObjFanin1(Abc_ObjFanin1(pFanin)) == pLatch) )
1878  {
1879  nJKFFs++;
1880  }
1881  }
1882  printf( "D = %6d. T = %6d. JK = %6d. (%6.2f %%)\n",
1883  Abc_NtkLatchNum(pNtk), nTFFs, nJKFFs, 100.0 * nJKFFs / Abc_NtkLatchNum(pNtk) );
1884 */
1885 }
1886 
1887 
1888 /**Function*************************************************************
1889 
1890  Synopsis [Compares the pointers.]
1891 
1892  Description []
1893 
1894  SideEffects []
1895 
1896  SeeAlso []
1897 
1898 ***********************************************************************/
1899 int Abc_ObjPointerCompare( void ** pp1, void ** pp2 )
1900 {
1901  if ( *pp1 < *pp2 )
1902  return -1;
1903  if ( *pp1 > *pp2 )
1904  return 1;
1905  return 0;
1906 }
1907 
1908 /**Function*************************************************************
1909 
1910  Synopsis [Adjusts the copy pointers.]
1911 
1912  Description [This procedure assumes that the network was transformed
1913  into another network, which was in turn transformed into yet another
1914  network. It makes the pCopy pointers of the original network point to
1915  the objects of the yet another network.]
1916 
1917  SideEffects []
1918 
1919  SeeAlso []
1920 
1921 ***********************************************************************/
1923 {
1924  Abc_Obj_t * pObj;
1925  int i;
1926  Abc_NtkForEachObj( pNtk, pObj, i )
1927  if ( !Abc_ObjIsNet(pObj) )
1928  pObj->pCopy = pObj->pCopy? Abc_ObjCopyCond(pObj->pCopy) : NULL;
1929 }
1930 
1931 
1932 /**Function*************************************************************
1933 
1934  Synopsis [Increaments the cut counter.]
1935 
1936  Description [Returns 1 if it becomes equal to the ref counter.]
1937 
1938  SideEffects []
1939 
1940  SeeAlso []
1941 
1942 ***********************************************************************/
1943 static inline int Abc_ObjCrossCutInc( Abc_Obj_t * pObj )
1944 {
1945 // pObj->pCopy = (void *)(((int)pObj->pCopy)++);
1946  int Value = (int)(ABC_PTRINT_T)pObj->pCopy;
1947  pObj->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)(Value + 1);
1948  return (int)(ABC_PTRINT_T)pObj->pCopy == Abc_ObjFanoutNum(pObj);
1949 }
1950 
1951 /**Function*************************************************************
1952 
1953  Synopsis [Computes cross-cut of the circuit.]
1954 
1955  Description [Returns 1 if it is the last visit to the node.]
1956 
1957  SideEffects []
1958 
1959  SeeAlso []
1960 
1961 ***********************************************************************/
1962 int Abc_NtkCrossCut_rec( Abc_Obj_t * pObj, int * pnCutSize, int * pnCutSizeMax )
1963 {
1964  Abc_Obj_t * pFanin;
1965  int i, nDecrem = 0;
1966  int fReverse = 0;
1967  if ( Abc_ObjIsCi(pObj) )
1968  return 0;
1969  // if visited, increment visit counter
1970  if ( Abc_NodeIsTravIdCurrent( pObj ) )
1971  return Abc_ObjCrossCutInc( pObj );
1972  Abc_NodeSetTravIdCurrent( pObj );
1973  // visit the fanins
1974  if ( !Abc_ObjIsCi(pObj) )
1975  {
1976  if ( fReverse )
1977  {
1978  Abc_ObjForEachFanin( pObj, pFanin, i )
1979  {
1980  pFanin = Abc_ObjFanin( pObj, Abc_ObjFaninNum(pObj) - 1 - i );
1981  nDecrem += Abc_NtkCrossCut_rec( pFanin, pnCutSize, pnCutSizeMax );
1982  }
1983  }
1984  else
1985  {
1986  Abc_ObjForEachFanin( pObj, pFanin, i )
1987  nDecrem += Abc_NtkCrossCut_rec( pFanin, pnCutSize, pnCutSizeMax );
1988  }
1989  }
1990  // count the node
1991  (*pnCutSize)++;
1992  if ( *pnCutSizeMax < *pnCutSize )
1993  *pnCutSizeMax = *pnCutSize;
1994  (*pnCutSize) -= nDecrem;
1995  return Abc_ObjCrossCutInc( pObj );
1996 }
1997 
1998 /**Function*************************************************************
1999 
2000  Synopsis [Computes cross-cut of the circuit.]
2001 
2002  Description []
2003 
2004  SideEffects []
2005 
2006  SeeAlso []
2007 
2008 ***********************************************************************/
2010 {
2011  Abc_Obj_t * pObj;
2012  int nCutSize = 0, nCutSizeMax = 0;
2013  int i;
2014  Abc_NtkCleanCopy( pNtk );
2015  Abc_NtkIncrementTravId( pNtk );
2016  Abc_NtkForEachCo( pNtk, pObj, i )
2017  {
2018  Abc_NtkCrossCut_rec( pObj, &nCutSize, &nCutSizeMax );
2019  nCutSize--;
2020  }
2021  assert( nCutSize == 0 );
2022  printf( "Max cross cut size = %6d. Ratio = %6.2f %%\n", nCutSizeMax, 100.0 * nCutSizeMax/Abc_NtkObjNum(pNtk) );
2023  return nCutSizeMax;
2024 }
2025 
2026 
2027 /**Function*************************************************************
2028 
2029  Synopsis [Prints all 3-var functions.]
2030 
2031  Description []
2032 
2033  SideEffects []
2034 
2035  SeeAlso []
2036 
2037 ***********************************************************************/
2039 {
2040  FILE * pFile;
2041  unsigned i;
2042  pFile = fopen( "4varfs.txt", "w" );
2043  for ( i = 1; i < (1<<16)-1; i++ )
2044  {
2045  fprintf( pFile, "read_truth " );
2046  Extra_PrintBinary( pFile, &i, 16 );
2047  fprintf( pFile, "; clp; st; w 1.blif; map; cec 1.blif\n" );
2048  }
2049  fclose( pFile );
2050 }
2051 
2052 
2053 static int * pSupps;
2054 
2055 /**Function*************************************************************
2056 
2057  Synopsis [Compares the supergates by their level.]
2058 
2059  Description []
2060 
2061  SideEffects []
2062 
2063  SeeAlso []
2064 
2065 ***********************************************************************/
2066 int Abc_NtkCompareConesCompare( int * pNum1, int * pNum2 )
2067 {
2068  if ( pSupps[*pNum1] > pSupps[*pNum2] )
2069  return -1;
2070  if ( pSupps[*pNum1] < pSupps[*pNum2] )
2071  return 1;
2072  return 0;
2073 }
2074 
2075 /**Function*************************************************************
2076 
2077  Synopsis [Analyze choice node support.]
2078 
2079  Description []
2080 
2081  SideEffects []
2082 
2083  SeeAlso []
2084 
2085 ***********************************************************************/
2087 {
2088  Vec_Ptr_t * vSupp, * vNodes, * vReverse;
2089  Abc_Obj_t * pObj, * pTemp;
2090  int Iter, i, k, Counter, CounterCos, CounterCosNew;
2091  int * pPerms;
2092 
2093  // sort COs by support size
2094  pPerms = ABC_ALLOC( int, Abc_NtkCoNum(pNtk) );
2095  pSupps = ABC_ALLOC( int, Abc_NtkCoNum(pNtk) );
2096  Abc_NtkForEachCo( pNtk, pObj, i )
2097  {
2098  pPerms[i] = i;
2099  vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
2100  pSupps[i] = Vec_PtrSize(vSupp);
2101  Vec_PtrFree( vSupp );
2102  }
2103  qsort( (void *)pPerms, Abc_NtkCoNum(pNtk), sizeof(int), (int (*)(const void *, const void *)) Abc_NtkCompareConesCompare );
2104 
2105  // consider COs in this order
2106  Iter = 0;
2107  Abc_NtkForEachCo( pNtk, pObj, i )
2108  {
2109  pObj = Abc_NtkCo( pNtk, pPerms[i] );
2110  if ( pObj->fMarkA )
2111  continue;
2112  Iter++;
2113 
2114  vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
2115  vNodes = Abc_NtkDfsNodes( pNtk, &pObj, 1 );
2116  vReverse = Abc_NtkDfsReverseNodesContained( pNtk, (Abc_Obj_t **)Vec_PtrArray(vSupp), Vec_PtrSize(vSupp) );
2117  // count the number of nodes in the reverse cone
2118  Counter = 0;
2119  for ( k = 1; k < Vec_PtrSize(vReverse) - 1; k++ )
2120  for ( pTemp = (Abc_Obj_t *)Vec_PtrEntry(vReverse, k); pTemp; pTemp = (Abc_Obj_t *)pTemp->pCopy )
2121  Counter++;
2122  CounterCos = CounterCosNew = 0;
2123  for ( pTemp = (Abc_Obj_t *)Vec_PtrEntryLast(vReverse); pTemp; pTemp = (Abc_Obj_t *)pTemp->pCopy )
2124  {
2125  assert( Abc_ObjIsCo(pTemp) );
2126  CounterCos++;
2127  if ( pTemp->fMarkA == 0 )
2128  CounterCosNew++;
2129  pTemp->fMarkA = 1;
2130  }
2131  // print statistics
2132  printf( "%4d CO %5d : Supp = %5d. Lev = %3d. Cone = %5d. Rev = %5d. COs = %3d (%3d).\n",
2133  Iter, pPerms[i], Vec_PtrSize(vSupp), Abc_ObjLevel(Abc_ObjFanin0(pObj)), Vec_PtrSize(vNodes), Counter, CounterCos, CounterCosNew );
2134 
2135  if ( Vec_PtrSize(vSupp) < 10 )
2136  {
2137  // free arrays
2138  Vec_PtrFree( vSupp );
2139  Vec_PtrFree( vNodes );
2140  Vec_PtrFree( vReverse );
2141  break;
2142  }
2143 
2144  // free arrays
2145  Vec_PtrFree( vSupp );
2146  Vec_PtrFree( vNodes );
2147  Vec_PtrFree( vReverse );
2148 
2149  }
2150  Abc_NtkForEachCo( pNtk, pObj, i )
2151  pObj->fMarkA = 0;
2152 
2153  ABC_FREE( pPerms );
2154  ABC_FREE( pSupps );
2155 }
2156 
2157 /**Function*************************************************************
2158 
2159  Synopsis [Analyze choice node support.]
2160 
2161  Description []
2162 
2163  SideEffects []
2164 
2165  SeeAlso []
2166 
2167 ***********************************************************************/
2169 {
2170  Vec_Ptr_t * vSupp;
2171  Abc_Obj_t * pObj, * pTemp;
2172  int i, nNodesOld;
2173  assert( Abc_NtkIsStrash(pNtk) );
2174  Abc_AigForEachAnd( pNtk, pObj, i )
2175  {
2176  if ( !Abc_AigNodeIsChoice(pObj) )
2177  continue;
2178 
2179  vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
2180  nNodesOld = Vec_PtrSize(vSupp);
2181  Vec_PtrFree( vSupp );
2182 
2183  for ( pTemp = (Abc_Obj_t *)pObj->pData; pTemp; pTemp = (Abc_Obj_t *)pTemp->pData )
2184  {
2185  vSupp = Abc_NtkNodeSupport( pNtk, &pTemp, 1 );
2186  if ( nNodesOld != Vec_PtrSize(vSupp) )
2187  printf( "Choice orig = %3d Choice new = %3d\n", nNodesOld, Vec_PtrSize(vSupp) );
2188  Vec_PtrFree( vSupp );
2189  }
2190  }
2191 }
2192 
2193 /**Function*************************************************************
2194 
2195  Synopsis [Complements the constraint outputs.]
2196 
2197  Description []
2198 
2199  SideEffects []
2200 
2201  SeeAlso []
2202 
2203 ***********************************************************************/
2205 {
2206  Abc_Obj_t * pObj;
2207  int i;
2208  if ( Abc_NtkConstrNum(pNtk) == 0 )
2209  return;
2210  Abc_NtkForEachPo( pNtk, pObj, i )
2211  {
2212  if ( i >= Abc_NtkPoNum(pNtk) - Abc_NtkConstrNum(pNtk) )
2213  Abc_ObjXorFaninC( pObj, 0 );
2214  }
2215 }
2216 
2217 /**Function*************************************************************
2218 
2219  Synopsis []
2220 
2221  Description []
2222 
2223  SideEffects []
2224 
2225  SeeAlso []
2226 
2227 ***********************************************************************/
2229 {
2230  Abc_Obj_t * pObj;
2231  int i;
2232  Abc_NtkForEachCi( pNtk, pObj, i )
2233  printf( "%c=%d ", 'a'+i, pObj->Level );
2234  printf( "\n" );
2235 }
2236 
2237 
2238 /**Function*************************************************************
2239 
2240  Synopsis [Returns 1 if all other fanouts of pFanin are below pNode.]
2241 
2242  Description []
2243 
2244  SideEffects []
2245 
2246  SeeAlso []
2247 
2248 ***********************************************************************/
2249 int Abc_NtkAddBuffsEval( Abc_Obj_t * pNode, Abc_Obj_t * pFanin )
2250 {
2251  Abc_Obj_t * pFanout;
2252  int i;
2253  Abc_ObjForEachFanout( pFanin, pFanout, i )
2254  if ( pFanout != pNode && pFanout->Level >= pNode->Level )
2255  return 0;
2256  return 1;
2257 }
2258 /**Function*************************************************************
2259 
2260  Synopsis [Returns 1 if there exist a fanout of pFanin higher than pNode.]
2261 
2262  Description []
2263 
2264  SideEffects []
2265 
2266  SeeAlso []
2267 
2268 ***********************************************************************/
2269 int Abc_NtkAddBuffsEval2( Abc_Obj_t * pNode, Abc_Obj_t * pFanin )
2270 {
2271  Abc_Obj_t * pFanout;
2272  int i;
2273  Abc_ObjForEachFanout( pFanin, pFanout, i )
2274  if ( pFanout != pNode && pFanout->Level > pNode->Level )
2275  return 1;
2276  return 0;
2277 }
2278 
2279 /**Function*************************************************************
2280 
2281  Synopsis []
2282 
2283  Description []
2284 
2285  SideEffects []
2286 
2287  SeeAlso []
2288 
2289 ***********************************************************************/
2290 Abc_Obj_t * Abc_NtkAddBuffsOne( Vec_Ptr_t * vBuffs, Abc_Obj_t * pFanin, int Level, int nLevelMax )
2291 {
2292  Abc_Obj_t * pBuffer;
2293  assert( Level - 1 >= Abc_ObjLevel(pFanin) );
2294  pBuffer = (Abc_Obj_t *)Vec_PtrEntry( vBuffs, Abc_ObjId(pFanin) * nLevelMax + Level );
2295  if ( pBuffer == NULL )
2296  {
2297  if ( Level - 1 == Abc_ObjLevel(pFanin) )
2298  pBuffer = pFanin;
2299  else
2300  pBuffer = Abc_NtkAddBuffsOne( vBuffs, pFanin, Level - 1, nLevelMax );
2301  pBuffer = Abc_NtkCreateNodeBuf( Abc_ObjNtk(pFanin), pBuffer );
2302  Vec_PtrWriteEntry( vBuffs, Abc_ObjId(pFanin) * nLevelMax + Level, pBuffer );
2303  }
2304  return pBuffer;
2305 }
2306 Abc_Ntk_t * Abc_NtkAddBuffsInt( Abc_Ntk_t * pNtkInit, int fReverse, int nImprove, int fVerbose )
2307 {
2308  Vec_Ptr_t * vBuffs;
2309  Abc_Ntk_t * pNtk = Abc_NtkDup( pNtkInit );
2310  Abc_Obj_t * pObj, * pFanin, * pBuffer;
2311  int i, k, Iter, nLevelMax = Abc_NtkLevel( pNtk );
2312  Abc_NtkForEachCo( pNtk, pObj, i )
2313  pObj->Level = nLevelMax + 1;
2314  if ( fReverse )
2315  {
2316  Vec_Ptr_t * vNodes = Abc_NtkDfs( pNtk, 1 );
2317  assert( nLevelMax < (1<<18) );
2318  Vec_PtrForEachEntryReverse( Abc_Obj_t *, vNodes, pObj, i )
2319  {
2320  pObj->Level = (1<<18);
2321  Abc_ObjForEachFanout( pObj, pFanin, k )
2322  pObj->Level = Abc_MinInt( pFanin->Level - 1, pObj->Level );
2323  assert( pObj->Level > 0 );
2324  }
2325  Abc_NtkForEachCi( pNtk, pObj, i )
2326  pObj->Level = 0;
2327 
2328  // move the nodes down one step at a time
2329  for ( Iter = 0; Iter < nImprove; Iter++ )
2330  {
2331  int Counter = 0, TotalGain = 0;
2332  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
2333  {
2334  int CountGain = -1;
2335  assert( pObj->Level > 0 );
2336  Abc_ObjForEachFanin( pObj, pFanin, k )
2337  {
2338  assert( pFanin->Level < pObj->Level );
2339  if ( pFanin->Level + 1 == pObj->Level )
2340  break;
2341  }
2342  if ( k < Abc_ObjFaninNum(pObj) ) // cannot move
2343  continue;
2344  Abc_ObjForEachFanin( pObj, pFanin, k )
2345  CountGain += Abc_NtkAddBuffsEval( pObj, pFanin );
2346  if ( CountGain >= 0 ) // can move
2347  {
2348  pObj->Level--;
2349  Counter++;
2350  TotalGain += CountGain;
2351  }
2352  }
2353  if ( fVerbose )
2354  printf( "Shifted %5d nodes down with total gain %5d.\n", Counter, TotalGain );
2355  if ( Counter == 0 )
2356  break;
2357  }
2358  Vec_PtrFree( vNodes );
2359  }
2360  else
2361  {
2362  // move the nodes up one step at a time
2363  Vec_Ptr_t * vNodes = Abc_NtkDfs( pNtk, 1 );
2364  for ( Iter = 0; Iter < nImprove; Iter++ )
2365  {
2366  int Counter = 0, TotalGain = 0;
2367  Vec_PtrForEachEntryReverse( Abc_Obj_t *, vNodes, pObj, i )
2368  {
2369  int CountGain = 1;
2370  assert( pObj->Level <= (unsigned)nLevelMax );
2371  Abc_ObjForEachFanout( pObj, pFanin, k )
2372  {
2373  assert( pFanin->Level > pObj->Level );
2374  if ( pFanin->Level == pObj->Level + 1 )
2375  break;
2376  }
2377  if ( k < Abc_ObjFanoutNum(pObj) ) // cannot move
2378  continue;
2379  Abc_ObjForEachFanin( pObj, pFanin, k )
2380  CountGain -= !Abc_NtkAddBuffsEval2( pObj, pFanin );
2381  if ( CountGain >= 0 ) // can move
2382  {
2383  pObj->Level++;
2384  Counter++;
2385  TotalGain += CountGain;
2386  }
2387  }
2388  if ( fVerbose )
2389  printf( "Shifted %5d nodes up with total gain %5d.\n", Counter, TotalGain );
2390  if ( Counter == 0 )
2391  break;
2392  }
2393  Vec_PtrFree( vNodes );
2394  }
2395  vBuffs = Vec_PtrStart( Abc_NtkObjNumMax(pNtk) * (nLevelMax + 1) );
2396  Abc_NtkForEachObj( pNtk, pObj, i )
2397  {
2398  if ( i == Vec_PtrSize(vBuffs) / (nLevelMax + 1) )
2399  break;
2400  if ( !Abc_ObjIsNode(pObj) && !Abc_ObjIsCo(pObj) )
2401  continue;
2402  Abc_ObjForEachFanin( pObj, pFanin, k )
2403  {
2404  assert( Abc_ObjLevel(pObj) - 1 >= Abc_ObjLevel(pFanin) );
2405  if ( Abc_ObjLevel(pObj) - 1 == Abc_ObjLevel(pFanin) )
2406  continue;
2407  pBuffer = Abc_NtkAddBuffsOne( vBuffs, pFanin, Abc_ObjLevel(pObj) - 1, nLevelMax );
2408  Abc_ObjPatchFanin( pObj, pFanin, pBuffer );
2409  }
2410  }
2411  Vec_PtrFree( vBuffs );
2412  Abc_NtkForEachCo( pNtk, pObj, i )
2413  pObj->Level = 0;
2414  return pNtk;
2415 }
2416 Abc_Ntk_t * Abc_NtkAddBuffs( Abc_Ntk_t * pNtkInit, int fDirect, int fReverse, int nImprove, int fVerbose )
2417 {
2418  Abc_Ntk_t * pNtkD, * pNtkR;
2419  if ( fDirect )
2420  return Abc_NtkAddBuffsInt( pNtkInit, 0, nImprove, fVerbose );
2421  if ( fReverse )
2422  return Abc_NtkAddBuffsInt( pNtkInit, 1, nImprove, fVerbose );
2423  pNtkD = Abc_NtkAddBuffsInt( pNtkInit, 0, nImprove, fVerbose );
2424  pNtkR = Abc_NtkAddBuffsInt( pNtkInit, 1, nImprove, fVerbose );
2425  if ( Abc_NtkNodeNum(pNtkD) < Abc_NtkNodeNum(pNtkR) )
2426  {
2427  Abc_NtkDelete( pNtkR );
2428  return pNtkD;
2429  }
2430  else
2431  {
2432  Abc_NtkDelete( pNtkD );
2433  return pNtkR;
2434  }
2435 }
2436 
2437 /**Function*************************************************************
2438 
2439  Synopsis [Computes max delay using log(n) delay model.]
2440 
2441  Description []
2442 
2443  SideEffects []
2444 
2445  SeeAlso []
2446 
2447 ***********************************************************************/
2449 {
2450  static double GateDelays[20] = { 1.00, 1.00, 2.00, 2.58, 3.00, 3.32, 3.58, 3.81, 4.00, 4.17, 4.32, 4.46, 4.58, 4.70, 4.81, 4.91, 5.00, 5.09, 5.17, 5.25 };
2451  Vec_Ptr_t * vNodes;
2452  Abc_Obj_t * pObj, * pFanin;
2453  float DelayMax, Delays[15] = {0};
2454  int nFaninMax, i, k;
2455  // calculate relative gate delays
2456  nFaninMax = Abc_NtkGetFaninMax( pNtk );
2457  assert( nFaninMax > 1 && nFaninMax < 15 );
2458  for ( i = 0; i <= nFaninMax; i++ )
2459  Delays[i] = GateDelays[i]/GateDelays[nFaninMax];
2460  // set max CI delay
2461  Abc_NtkForEachCi( pNtk, pObj, i )
2462  pObj->dTemp = 0.0;
2463  // compute delays for each node
2464  vNodes = Abc_NtkDfs( pNtk, 1 );
2465  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
2466  {
2467  pObj->dTemp = 0.0;
2468  Abc_ObjForEachFanin( pObj, pFanin, k )
2469  pObj->dTemp = Abc_MaxFloat( pObj->dTemp, pFanin->dTemp );
2470  pObj->dTemp += Delays[Abc_ObjFaninNum(pObj)];
2471  }
2472  Vec_PtrFree( vNodes );
2473  DelayMax = 0.0;
2474  // find max CO delay
2475  Abc_NtkForEachCo( pNtk, pObj, i )
2476  DelayMax = Abc_MaxFloat( DelayMax, Abc_ObjFanin0(pObj)->dTemp );
2477  return DelayMax;
2478 }
2479 
2480 
2481 /**Function*************************************************************
2482 
2483  Synopsis []
2484 
2485  Description []
2486 
2487  SideEffects []
2488 
2489  SeeAlso []
2490 
2491 ***********************************************************************/
2492 void Abc_NodeSopToCubes( Abc_Obj_t * pNodeOld, Abc_Ntk_t * pNtkNew )
2493 {
2494  Abc_Obj_t * pNodeOr, * pNodeNew, * pFanin;
2495  char * pCube, * pSop = (char *)pNodeOld->pData;
2496  int v, Value, nVars = Abc_ObjFaninNum(pNodeOld), nFanins;
2497  // create the root node
2498  if ( Abc_SopGetCubeNum(pSop) < 2 )
2499  {
2500  pNodeNew = Abc_NtkDupObj( pNtkNew, pNodeOld, 0 );
2501  Abc_ObjForEachFanin( pNodeOld, pFanin, v )
2502  Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
2503  assert( pNodeOld->pCopy == pNodeNew );
2504  return;
2505  }
2506  // add the OR gate
2507  pNodeOr = Abc_NtkCreateNode( pNtkNew );
2508  pNodeOr->pData = Abc_SopCreateOr( (Mem_Flex_t *)pNtkNew->pManFunc, Abc_SopGetCubeNum(pSop), NULL );
2509  // check the logic function of the node
2510  Abc_SopForEachCube( pSop, nVars, pCube )
2511  {
2512  nFanins = 0;
2513  Abc_CubeForEachVar( pCube, Value, v )
2514  if ( Value == '0' || Value == '1' )
2515  nFanins++;
2516  assert( nFanins > 0 );
2517  // create node
2518  pNodeNew = Abc_NtkCreateNode( pNtkNew );
2519  pNodeNew->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, nFanins, NULL );
2520  nFanins = 0;
2521  Abc_CubeForEachVar( pCube, Value, v )
2522  {
2523  if ( Value != '0' && Value != '1' )
2524  continue;
2525  Abc_ObjAddFanin( pNodeNew, Abc_ObjFanin(pNodeOld, v)->pCopy );
2526  if ( Value == '0' )
2527  Abc_SopComplementVar( (char *)pNodeNew->pData, nFanins );
2528  nFanins++;
2529  }
2530  Abc_ObjAddFanin( pNodeOr, pNodeNew );
2531  }
2532  // check the complement
2533  if ( Abc_SopIsComplement(pSop) )
2534  Abc_SopComplement( (char *)pNodeOr->pData );
2535  // mark the old node with the new one
2536  assert( pNodeOld->pCopy == NULL );
2537  pNodeOld->pCopy = pNodeOr;
2538 }
2540 {
2541  Abc_Ntk_t * pNtkNew;
2542  Abc_Obj_t * pNode;
2543  Vec_Ptr_t * vNodes;
2544  int i;
2545  assert( Abc_NtkIsSopLogic(pNtk) );
2546  Abc_NtkCleanCopy( pNtk );
2547  pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
2548  // perform conversion in the topological order
2549  vNodes = Abc_NtkDfs( pNtk, 0 );
2550  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
2551  Abc_NodeSopToCubes( pNode, pNtkNew );
2552  Vec_PtrFree( vNodes );
2553  // make sure everything is okay
2554  Abc_NtkFinalize( pNtk, pNtkNew );
2555  if ( !Abc_NtkCheck( pNtkNew ) )
2556  {
2557  printf( "Abc_NtkSopToCubes: The network check has failed.\n" );
2558  Abc_NtkDelete( pNtkNew );
2559  return NULL;
2560  }
2561  return pNtkNew;
2562 }
2563 
2564 /**Function*************************************************************
2565 
2566  Synopsis [Creates precomputed reverse topological order for each node.]
2567 
2568  Description []
2569 
2570  SideEffects []
2571 
2572  SeeAlso []
2573 
2574 ***********************************************************************/
2575 static inline int Abc_NtkTopoHasBeg( Abc_Obj_t * p ) { return Vec_IntEntry(p->pNtk->vTopo, 2*Abc_ObjId(p) ); }
2576 static inline int Abc_NtkTopoHasEnd( Abc_Obj_t * p ) { return Vec_IntEntry(p->pNtk->vTopo, 2*Abc_ObjId(p)+1); }
2577 
2578 static inline void Abc_NtkTopoSetBeg( Abc_Obj_t * p ) { Vec_IntWriteEntry(p->pNtk->vTopo, 2*Abc_ObjId(p) , Vec_IntSize(p->pNtk->vTopo)); }
2579 static inline void Abc_NtkTopoSetEnd( Abc_Obj_t * p ) { Vec_IntWriteEntry(p->pNtk->vTopo, 2*Abc_ObjId(p)+1, Vec_IntSize(p->pNtk->vTopo)); }
2580 
2581 void Abc_NtkReverseTopoOrder_rec( Abc_Obj_t * pObj, int fThisIsPivot )
2582 {
2583  Abc_Obj_t * pNext, * pPivot = NULL;
2584  int i;
2585  if ( Abc_NodeIsTravIdCurrent( pObj ) )
2586  return;
2587  Abc_NodeSetTravIdCurrent( pObj );
2588  if ( Abc_ObjIsPo(pObj) )
2589  {
2590  Vec_IntPush( pObj->pNtk->vTopo, Abc_ObjId(pObj) );
2591  return;
2592  }
2593  assert( Abc_ObjIsNode(pObj) );
2594  // mark begining
2595  if ( fThisIsPivot )
2596  Abc_NtkTopoSetBeg( pObj );
2597  // find fanout without topo
2598  Abc_ObjForEachFanout( pObj, pNext, i )
2599  if ( !Abc_NtkTopoHasBeg(pNext) )
2600  {
2601  assert( !Abc_NtkTopoHasEnd(pNext) );
2602  Abc_NtkReverseTopoOrder_rec( pNext, 1 );
2603  pPivot = pNext;
2604  break;
2605  }
2606  Abc_ObjForEachFanout( pObj, pNext, i )
2607  if ( pNext != pPivot )
2608  Abc_NtkReverseTopoOrder_rec( pNext, 0 );
2609  // mark end
2610  if ( fThisIsPivot )
2611  Abc_NtkTopoSetEnd( pObj );
2612  // save current node
2613  Vec_IntPush( pObj->pNtk->vTopo, Abc_ObjId(pObj) );
2614 }
2616 {
2617  Abc_Obj_t * pObj;
2618  int i;
2619  assert( p->vTopo == NULL );
2620  p->vTopo = Vec_IntAlloc( 10 * Abc_NtkObjNumMax(p) );
2621  Vec_IntFill( p->vTopo, 2 * Abc_NtkObjNumMax(p), 0 );
2622  Abc_NtkForEachNode( p, pObj, i )
2623  {
2624  if ( Abc_NtkTopoHasBeg(pObj) )
2625  continue;
2626  Abc_NtkIncrementTravId( p );
2627  Abc_NtkReverseTopoOrder_rec( pObj, 1 );
2628  }
2629  printf( "Nodes = %d. Size = %d. Ratio = %f.\n",
2631 }
2632 
2633 void Abc_NtkReverse_rec( Abc_Obj_t * pObj, Vec_Int_t * vVisited )
2634 {
2635  Abc_Obj_t * pNext;
2636  int i;
2637  if ( Abc_NodeIsTravIdCurrent( pObj ) )
2638  return;
2639  Abc_NodeSetTravIdCurrent( pObj );
2640  Abc_ObjForEachFanout( pObj, pNext, i )
2641  Abc_NtkReverse_rec( pNext, vVisited );
2642  Vec_IntPush( vVisited, Abc_ObjId(pObj) );
2643 }
2645 {
2646  Vec_Int_t * vVisited;
2647  Abc_Obj_t * pObj;
2648  int i;//, k, iBeg, iEnd;
2649  abctime clk = Abc_Clock();
2651 /*
2652  printf( "Reverse topological order for nodes:\n" );
2653  Abc_NtkForEachNode( p, pObj, i )
2654  {
2655  iBeg = Abc_NtkTopoHasBeg( pObj );
2656  iEnd = Abc_NtkTopoHasEnd( pObj );
2657  printf( "Node %4d : ", Abc_ObjId(pObj) );
2658  for ( k = iEnd - 1; k >= iBeg; k-- )
2659  printf( "%d ", Vec_IntEntry(p->vTopo, k) );
2660  printf( "\n" );
2661  }
2662 */
2663  Vec_IntFreeP( &p->vTopo );
2664  Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
2665  // compute regular fanout orders
2666  clk = Abc_Clock();
2667  vVisited = Vec_IntAlloc( 1000 );
2668  Abc_NtkForEachNode( p, pObj, i )
2669  {
2670  Vec_IntClear( vVisited );
2671  Abc_NtkIncrementTravId( p );
2672  Abc_NtkReverse_rec( pObj, vVisited );
2673  }
2674  Vec_IntFree( vVisited );
2675  Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
2676 }
2677 
2678 /**Function*************************************************************
2679 
2680  Synopsis [Converts multi-output PLA into an AIG with logic sharing.]
2681 
2682  Description [The first argument is an array of char*-strings representing
2683  individual output of a multi-output PLA. The number of inputs (nInputs)
2684  and the number of outputs (nOutputs) are the second and third arguments.
2685  This procedure returns the AIG manager with the given number of inputs
2686  and outputs representing the PLA as a logic network with sharing.
2687 
2688  For example, if the original PLA is
2689  1000 10
2690  0110 01
2691  0011 01
2692  the individual PLA for each the two outputs should be
2693  1000 1
2694  and
2695  0110 1
2696  0011 1
2697 
2698  Reprsentation in terms of two char*-strings will be:
2699  char * pPlas[2] = { "1000 1\n", "0110 1\n0011 1\n" };
2700  The call to the procedure may look as follows:
2701  Abc_Ntk_t * pNtkAig = Abc_NtkFromPla( pPlas, 4, 2 );]
2702 
2703  SideEffects []
2704 
2705  SeeAlso []
2706 
2707 ***********************************************************************/
2708 Abc_Ntk_t * Abc_NtkFromPla( char ** pPlas, int nInputs, int nOutputs )
2709 {
2710  Fxu_Data_t Params, * p = &Params;
2711  Abc_Ntk_t * pNtkSop, * pNtkAig;
2712  Abc_Obj_t * pNode, * pFanin;
2713  int i, k;
2714  // allocate logic network with SOP local functions
2715  pNtkSop = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
2716  pNtkSop->pName = Extra_FileNameGeneric("pla");
2717  // create primary inputs/outputs
2718  for ( i = 0; i < nInputs; i++ )
2719  Abc_NtkCreatePi( pNtkSop );
2720  for ( i = 0; i < nOutputs; i++ )
2721  Abc_NtkCreatePo( pNtkSop );
2722  Abc_NtkAddDummyPiNames( pNtkSop );
2723  Abc_NtkAddDummyPoNames( pNtkSop );
2724  // create internal nodes
2725  for ( i = 0; i < nOutputs; i++ )
2726  {
2727  pNode = Abc_NtkCreateNode( pNtkSop );
2728  Abc_NtkForEachPi( pNtkSop, pFanin, k )
2729  Abc_ObjAddFanin( pNode, pFanin );
2730  pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkSop->pManFunc, pPlas[i] );
2731  Abc_ObjAddFanin( Abc_NtkPo(pNtkSop, i), pNode );
2732  // check that the number of inputs is the same
2733  assert( Abc_SopGetVarNum((char*)pNode->pData) == nInputs );
2734  }
2735  if ( !Abc_NtkCheck( pNtkSop ) )
2736  fprintf( stdout, "Abc_NtkFromPla(): Network check has failed.\n" );
2737  // perform fast_extract
2739  Abc_NtkFastExtract( pNtkSop, p );
2740  Abc_NtkFxuFreeInfo( p );
2741  // convert to an AIG
2742  pNtkAig = Abc_NtkStrash( pNtkSop, 0, 1, 0 );
2743  Abc_NtkDelete( pNtkSop );
2744  return pNtkAig;
2745 }
2747 {
2748  char * pPlas[2] = { "1000 1\n", "0110 1\n0011 1\n" };
2749  Abc_Ntk_t * pNtkAig = Abc_NtkFromPla( pPlas, 4, 2 );
2750  Io_WriteBlifLogic( pNtkAig, "temp.blif", 0 );
2751  Abc_NtkDelete( pNtkAig );
2752 }
2753 
2754 /**Function*************************************************************
2755 
2756  Synopsis [Checks if the logic network is in the topological order.]
2757 
2758  Description []
2759 
2760  SideEffects []
2761 
2762  SeeAlso []
2763 
2764 ***********************************************************************/
2765 Abc_Ntk_t * Abc_NtkSplitSop( Abc_Ntk_t * pNtk, int nCubesMax, int fVerbose )
2766 {
2767  Vec_Ptr_t * vNodes;
2768  Abc_Ntk_t * pNtkNew;
2769  Abc_Obj_t * pObj, * pFanin, * pObjNew, * pObjNewRoot;
2770  int i, k, j, nCubes, nCubesThis, nSplits;
2771  char * pSopStr, * pSopStr2, * pTempSop, Symb;
2772  if ( pNtk == NULL )
2773  return NULL;
2774  assert( !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsNetlist(pNtk) );
2775  // start the network
2776  pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
2777  // copy the internal nodes
2778  vNodes = Abc_NtkDfs( pNtk, 0 );
2779  Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
2780  {
2781  assert( Abc_ObjIsNode(pObj) );
2782  pObjNewRoot = Abc_NtkDupObj( pNtkNew, pObj, 0 );
2783  nCubes = Abc_SopGetCubeNum( (char *)pObj->pData );
2784  if ( nCubes <= nCubesMax )
2785  {
2786  Abc_ObjForEachFanin( pObj, pFanin, k )
2787  Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
2788  continue;
2789  }
2790  nSplits = (nCubes / nCubesMax) + (int)(nCubes % nCubesMax > 0);
2791  pSopStr = (char *)pObjNewRoot->pData;
2792  pObjNewRoot->pData = Abc_SopCreateOr((Mem_Flex_t *)pNtkNew->pManFunc, nSplits, NULL);
2793  if ( Abc_SopIsComplement(pSopStr) )
2794  {
2795  Abc_SopComplement( pSopStr );
2796  Abc_SopComplement( (char *)pObjNewRoot->pData );
2797  }
2798  pTempSop = (char *)pObj->pData; pObj->pData = (char *)"?";
2799  for ( j = 0; j < nSplits; j++ )
2800  {
2801  // clone the node
2802  pObjNew = Abc_NtkDupObj( pNtkNew, pObj, 0 );
2803  Abc_ObjAddFanin( pObjNewRoot, pObjNew );
2804  // get its cubes
2805  Abc_ObjForEachFanin( pObj, pFanin, k )
2806  Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
2807  // create SOP for this node
2808  nCubesThis = (j < nCubes / nCubesMax) ? nCubesMax : nCubes % nCubesMax;
2809  pSopStr2 = pSopStr + (Abc_ObjFaninNum(pObj) + 3) * nCubesThis;
2810  Symb = *pSopStr2; *pSopStr2 = 0;
2811  pObjNew->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, pSopStr );
2812  *pSopStr2 = Symb;
2813  pSopStr = pSopStr2;
2814  }
2815  // update
2816  pObj->pData = pTempSop;
2817  pObj->pCopy = pObjNewRoot;
2818  }
2819  Vec_PtrFree( vNodes );
2820  Abc_NtkFinalize( pNtk, pNtkNew );
2821  // check correctness
2822  if ( !Abc_NtkCheck( pNtkNew ) )
2823  fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
2824  pNtk->pCopy = pNtkNew;
2825  return pNtkNew;
2826 }
2827 
2828 /**Function*************************************************************
2829 
2830  Synopsis [Checks if the logic network is in the topological order.]
2831 
2832  Description []
2833 
2834  SideEffects []
2835 
2836  SeeAlso []
2837 
2838 ***********************************************************************/
2840 {
2841  Abc_Obj_t * pObj, * pFanin;
2842  int i, k, Counter = 0;
2843  Abc_NtkIncrementTravId( pNtk );
2844  Abc_NtkForEachCi( pNtk, pObj, i )
2846  Abc_NtkForEachNode( pNtk, pObj, i )
2847  {
2848  // check if fanins are in the topo order
2849  Abc_ObjForEachFanin( pObj, pFanin, k )
2850  if ( !Abc_NodeIsTravIdCurrent(pFanin) )
2851  break;
2852  if ( k != Abc_ObjFaninNum(pObj) )
2853  {
2854  if ( Counter++ == 0 )
2855  printf( "Node %d is out of topo order.\n", Abc_ObjId(pObj) );
2856  }
2858  }
2859  if ( Counter )
2860  printf( "Topological order does not hold for %d internal nodes.\n", Counter );
2861  return (int)(Counter == 0);
2862 }
2863 
2864 /**Function*************************************************************
2865 
2866  Synopsis [Transfers phase information to the new network.]
2867 
2868  Description []
2869 
2870  SideEffects []
2871 
2872  SeeAlso []
2873 
2874 ***********************************************************************/
2875 void Abc_NtkTransferPhases( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk )
2876 {
2877  Abc_Obj_t * pObj;
2878  int i;
2879  assert( pNtk->vPhases != NULL );
2880  assert( Vec_IntSize(pNtk->vPhases) == Abc_NtkObjNumMax(pNtk) );
2881  assert( pNtkNew->vPhases == NULL );
2882  pNtkNew->vPhases = Vec_IntStart( Abc_NtkObjNumMax(pNtkNew) );
2883  Abc_NtkForEachObj( pNtk, pObj, i )
2884  if ( pObj->pCopy && !Abc_ObjIsNone( (Abc_Obj_t *)pObj->pCopy ) )
2885  Vec_IntWriteEntry( pNtkNew->vPhases, Abc_ObjId( (Abc_Obj_t *)pObj->pCopy ), Vec_IntEntry(pNtk->vPhases, i) );
2886 }
2887 
2888 ////////////////////////////////////////////////////////////////////////
2889 /// END OF FILE ///
2890 ////////////////////////////////////////////////////////////////////////
2891 
2892 
2894 
void Abc_NtkFromPlaTest()
Definition: abcUtil.c:2746
int Abc_NtkGetLitFactNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:189
int iTemp
Definition: abc.h:149
static unsigned Abc_ObjId(Abc_Obj_t *pObj)
Definition: abc.h:329
static Abc_Obj_t * Abc_ObjCopyCond(Abc_Obj_t *pObj)
Definition: abc.h:338
static Vec_Ptr_t * Vec_PtrStart(int nSize)
Definition: vecPtr.h:106
Vec_Ptr_t * vAttrs
Definition: abc.h:214
int Abc_NtkLogicMakeSimpleCos2(Abc_Ntk_t *pNtk, int fDuplicate)
Definition: abcUtil.c:954
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:385
static int Abc_NtkIsStrash(Abc_Ntk_t *pNtk)
Definition: abc.h:251
static int Abc_NtkIsLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:250
void Abc_NtkCleanCopy_rec(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:514
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition: vecPtr.h:42
static Abc_Obj_t * Abc_ObjFanin1(Abc_Obj_t *pObj)
Definition: abc.h:374
static int Abc_NtkHasSop(Abc_Ntk_t *pNtk)
Definition: abc.h:253
static int Abc_ObjIsCi(Abc_Obj_t *pObj)
Definition: abc.h:351
unsigned fMarkA
Definition: abc.h:134
ABC_DLL int Abc_NodeIsConst(Abc_Obj_t *pNode)
Definition: abcObj.c:843
Abc_Ntk_t * Abc_NtkFromPla(char **pPlas, int nInputs, int nOutputs)
Definition: abcUtil.c:2708
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
static int Dec_GraphNodeNum(Dec_Graph_t *pGraph)
Definition: dec.h:421
Vec_Int_t * vTopo
Definition: abc.h:213
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
static int Abc_NtkObjNumMax(Abc_Ntk_t *pNtk)
Definition: abc.h:284
int Abc_NtkGetExorNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:370
void Abc_NtkCleanNext(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:636
int Abc_NtkPrepareTwoNtks(FILE *pErr, Abc_Ntk_t *pNtk, char **argv, int argc, Abc_Ntk_t **ppNtk1, Abc_Ntk_t **ppNtk2, int *pfDelete1, int *pfDelete2)
Definition: abcUtil.c:1481
ABC_DLL Abc_Obj_t * Abc_AigConst1(Abc_Ntk_t *pNtk)
Definition: abcAig.c:683
int Abc_NtkGetFaninMax(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:453
int Hop_DagSize(Hop_Obj_t *pObj)
Definition: hopDfs.c:279
static Llb_Mgr_t * p
Definition: llb3Image.c:950
void Abc_NtkCleanMarkC(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:701
static int Abc_ObjFaninC1(Abc_Obj_t *pObj)
Definition: abc.h:378
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition: bblif.c:37
#define Vec_PtrForEachEntryReverse(Type, vVec, pEntry, i)
Definition: vecPtr.h:63
static int Vec_PtrPushUnique(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:656
static int Abc_NtkIsNetlist(Abc_Ntk_t *pNtk)
Definition: abc.h:249
Abc_Obj_t * Abc_NodeFindCoFanout(Abc_Obj_t *pNode)
Definition: abcUtil.c:779
int Abc_NtkLogicMakeSimpleCos(Abc_Ntk_t *pNtk, int fDuplicate)
Definition: abcUtil.c:1047
static int Abc_ObjIsLatch(Abc_Obj_t *pObj)
Definition: abc.h:356
void Abc_NtkReverseTopoOrder(Abc_Ntk_t *p)
Definition: abcUtil.c:2615
#define Abc_SopForEachCube(pSop, nFanins, pCube)
Definition: abc.h:531
ABC_DLL int Abc_NodeIsConst0(Abc_Obj_t *pNode)
Definition: abcObj.c:860
static int Abc_ObjFanoutNum(Abc_Obj_t *pObj)
Definition: abc.h:365
int util_optind
void Abc_NtkTransferPhases(Abc_Ntk_t *pNtkNew, Abc_Ntk_t *pNtk)
Definition: abcUtil.c:2875
ABC_DLL Abc_Ntk_t * Abc_NtkStrash(Abc_Ntk_t *pNtk, int fAllNodes, int fCleanup, int fRecord)
Definition: abcStrash.c:265
ABC_DLL int Abc_SopGetCubeNum(char *pSop)
Definition: abcSop.c:489
void Abc_NtkFxuFreeInfo(Fxu_Data_t *p)
Definition: abcFxu.c:207
void Abc_NtkFixCoDriverProblem(Abc_Obj_t *pDriver, Abc_Obj_t *pNodeCo, int fDuplicate)
Definition: abcUtil.c:858
ABC_DLL char * Abc_SopCreateAnd(Mem_Flex_t *pMan, int nVars, int *pfCompl)
Definition: abcSop.c:162
typedefABC_NAMESPACE_HEADER_START struct FxuDataStruct Fxu_Data_t
INCLUDES ///.
Definition: fxu.h:42
static int Abc_ObjFaninNum(Abc_Obj_t *pObj)
Definition: abc.h:364
static int Abc_ObjIsBarBuf(Abc_Obj_t *pObj)
Definition: abc.h:360
static int Abc_NtkHasMapping(Abc_Ntk_t *pNtk)
Definition: abc.h:256
ABC_DLL Abc_Obj_t * Abc_NtkDupObj(Abc_Ntk_t *pNtkNew, Abc_Obj_t *pObj, int fCopyName)
Definition: abcObj.c:337
Vec_Ptr_t * Abc_NtkCollectLatches(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:1627
int Abc_NodeIsMuxType(Abc_Obj_t *pNode)
Definition: abcUtil.c:1301
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeConst1(Abc_Ntk_t *pNtk)
Definition: abcObj.c:633
static int Abc_ObjFaninC0(Abc_Obj_t *pObj)
Definition: abc.h:377
ABC_DLL int Abc_SopGetLitNum(char *pSop)
Definition: abcSop.c:511
ABC_DLL Abc_Ntk_t * Abc_NtkDup(Abc_Ntk_t *pNtk)
Definition: abcNtk.c:419
Vec_Int_t vFanins
Definition: abc.h:143
double Abc_NtkGetMappedArea(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:334
static void Vec_PtrPush(Vec_Ptr_t *p, void *Entry)
Definition: vecPtr.h:606
static int Abc_NtkCiNum(Abc_Ntk_t *pNtk)
Definition: abc.h:287
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
Abc_Obj_t * Abc_NtkAddBuffsOne(Vec_Ptr_t *vBuffs, Abc_Obj_t *pFanin, int Level, int nLevelMax)
Definition: abcUtil.c:2290
float dTemp
Definition: abc.h:150
#define Abc_NtkForEachCo(pNtk, pCo, i)
Definition: abc.h:519
void Abc_NtkCleanMarkA(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:663
Vec_Ptr_t * vObjs
Definition: abc.h:162
Vec_Int_t * Abc_NtkFanoutCounts(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:1701
static void Abc_NtkTopoSetBeg(Abc_Obj_t *p)
Definition: abcUtil.c:2578
int Abc_NtkGetMuxNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:390
int Abc_NtkGetCubePairNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:138
int Abc_NtkFastExtract(Abc_Ntk_t *pNtk, Fxu_Data_t *p)
Definition: abcFxu.c:83
Dec_Graph_t * Dec_Factor(char *pSop)
FUNCTION DECLARATIONS ///.
Definition: decFactor.c:55
int Abc_ObjPointerCompare(void **pp1, void **pp2)
Definition: abcUtil.c:1899
ABC_DLL int Abc_NtkCheck(Abc_Ntk_t *pNtk)
FUNCTION DEFINITIONS ///.
Definition: abcCheck.c:61
static int Abc_NtkIsSopLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:264
#define Abc_CubeForEachVar(pCube, Value, i)
Definition: abc.h:529
int Abc_NtkGetClauseNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:293
ABC_DLL Vec_Ptr_t * Abc_NtkDfs(Abc_Ntk_t *pNtk, int fCollectAll)
Definition: abcDfs.c:81
ABC_DLL void Abc_AigRehash(Abc_Aig_t *pMan)
Definition: abcAig.c:628
static abctime Abc_Clock()
Definition: abc_global.h:279
int Abc_NtkAddBuffsEval(Abc_Obj_t *pNode, Abc_Obj_t *pFanin)
Definition: abcUtil.c:2249
static int Vec_PtrSize(Vec_Ptr_t *p)
Definition: vecPtr.h:295
int Abc_NtkCrossCut(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:2009
static int Abc_NtkIsAigLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:266
static Abc_Obj_t * Abc_ObjFanin0(Abc_Obj_t *pObj)
Definition: abc.h:373
static float Abc_MaxFloat(float a, float b)
Definition: abc_global.h:243
static int Abc_ObjFaninId0(Abc_Obj_t *pObj)
Definition: abc.h:367
Definition: hop.h:65
Vec_Ptr_t * Abc_NtkSaveCopy(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:595
static int Abc_NtkCoNum(Abc_Ntk_t *pNtk)
Definition: abc.h:288
DECLARATIONS ///.
Definition: abcAig.c:52
static int Abc_ObjIsNone(Abc_Obj_t *pObj)
Definition: abc.h:346
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
Definition: abcNtk.c:1233
unsigned Level
Definition: abc.h:142
static int Abc_ObjIsCo(Abc_Obj_t *pObj)
Definition: abc.h:352
int Abc_NtkGetBufNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:410
static Abc_Ntk_t * Abc_ObjModel(Abc_Obj_t *pObj)
Definition: abc.h:335
static Abc_Obj_t * Abc_NtkCo(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:318
Abc_Ntk_t * Io_Read(char *pFileName, Io_FileType_t FileType, int fCheck, int fBarBufs)
Definition: ioUtil.c:238
int nObjs
Definition: abc.h:172
void Abc_NtkCleanMarkAB(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:720
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
Definition: abcFanio.c:84
ABC_DLL Abc_Ntk_t * Abc_NtkAlloc(Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan)
DECLARATIONS ///.
Definition: abcNtk.c:50
int strcmp()
int Abc_NtkGetFanoutMax(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:464
Vec_Ptr_t * vCis
Definition: abc.h:165
ABC_DLL void Abc_SopComplementVar(char *pSop, int iVar)
Definition: abcSop.c:630
#define Abc_AigForEachAnd(pNtk, pNode, i)
Definition: abc.h:485
int Abc_NtkGetCubeNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:112
static Abc_Obj_t * Abc_ObjChild0(Abc_Obj_t *pObj)
Definition: abc.h:383
static void Abc_PrintTime(int level, const char *pStr, abctime time)
Definition: abc_global.h:367
ABC_DLL void Abc_ObjPatchFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFaninOld, Abc_Obj_t *pFaninNew)
Definition: abcFanio.c:172
Io_FileType_t Io_ReadFileType(char *pFileName)
DECLARATIONS ///.
Definition: ioUtil.c:46
static void Abc_NtkTopoSetEnd(Abc_Obj_t *p)
Definition: abcUtil.c:2579
static void Vec_IntWriteEntry(Vec_Int_t *p, int i, int Entry)
Definition: bblif.c:285
int Abc_NtkLogicHasSimpleCos(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:909
void * pManFunc
Definition: abc.h:191
static int Abc_ObjIsNode(Abc_Obj_t *pObj)
Definition: abc.h:355
static int Abc_NtkNodeNum(Abc_Ntk_t *pNtk)
Definition: abc.h:293
static int Abc_MinInt(int a, int b)
Definition: abc_global.h:239
ABC_DLL void Abc_NtkAddDummyPoNames(Abc_Ntk_t *pNtk)
Definition: abcNames.c:398
int Abc_NtkAddBuffsEval2(Abc_Obj_t *pNode, Abc_Obj_t *pFanin)
Definition: abcUtil.c:2269
static Vec_Int_t * Vec_IntStart(int nSize)
Definition: bblif.c:172
void Abc_VecObjPushUniqueOrderByLevel(Vec_Ptr_t *p, Abc_Obj_t *pNode)
Definition: abcUtil.c:1228
ABC_DLL char * Abc_SopRegister(Mem_Flex_t *pMan, char *pName)
DECLARATIONS ///.
Definition: abcSop.c:56
ABC_DLL Abc_Ntk_t * Abc_NtkStartFrom(Abc_Ntk_t *pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func)
Definition: abcNtk.c:106
Abc_Obj_t * pCopy
Definition: abc.h:148
ABC_DLL void Abc_NtkDeleteObj(Abc_Obj_t *pObj)
Definition: abcObj.c:167
void Abc_NtkInvertConstraints(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:2204
static Vec_Int_t * Vec_IntAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: bblif.c:149
Vec_Ptr_t * vCos
Definition: abc.h:166
static void * Vec_PtrEntryLast(Vec_Ptr_t *p)
Definition: vecPtr.h:413
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeInv(Abc_Ntk_t *pNtk, Abc_Obj_t *pFanin)
Definition: abcObj.c:662
Abc_Obj_t * Abc_NodeHasUniqueCoFanout(Abc_Obj_t *pNode)
Definition: abcUtil.c:823
static int Abc_ObjLevel(Abc_Obj_t *pObj)
Definition: abc.h:330
unsigned fMarkC
Definition: abc.h:136
int Abc_NtkIsTopo(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:2839
Abc_Ntk_t * Abc_NtkSplitSop(Abc_Ntk_t *pNtk, int nCubesMax, int fVerbose)
Definition: abcUtil.c:2765
char * Extra_FileNameGeneric(char *FileName)
static int Vec_IntEntry(Vec_Int_t *p, int i)
Definition: bblif.c:268
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
static void Vec_IntFill(Vec_Int_t *p, int nSize, int Fill)
Definition: bblif.c:356
void Abc_NtkPrint256()
Definition: abcUtil.c:2038
int Abc_NtkCountCopy(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:572
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeBuf(Abc_Ntk_t *pNtk, Abc_Obj_t *pFanin)
Definition: abcObj.c:692
ABC_DLL Vec_Ptr_t * Abc_NtkNodeSupport(Abc_Ntk_t *pNtk, Abc_Obj_t **ppNodes, int nNodes)
Definition: abcDfs.c:859
if(last==0)
Definition: sparse_int.h:34
ABC_DLL void Abc_NtkFinalize(Abc_Ntk_t *pNtk, Abc_Ntk_t *pNtkNew)
Definition: abcNtk.c:302
static int Abc_AigNodeIsAnd(Abc_Obj_t *pNode)
Definition: abc.h:397
void Abc_NtkPrintCiLevels(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:2228
int Abc_NtkCountMuxes(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:1336
void Abc_NtkLogicMakeSimpleCosTest(Abc_Ntk_t *pNtk, int fDuplicate)
Definition: abcUtil.c:1008
void Abc_NtkCleanMarkABC(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:739
DdNode * Cudd_zddIsop(DdManager *dd, DdNode *L, DdNode *U, DdNode **zdd_I)
Definition: cuddZddIsop.c:136
Vec_Int_t * vPhases
Definition: abc.h:208
Abc_Obj_t * Abc_NodeFindNonCoFanout(Abc_Obj_t *pNode)
Definition: abcUtil.c:800
static void Vec_IntPush(Vec_Int_t *p, int Entry)
Definition: bblif.c:468
void Abc_NtkLoadCopy(Abc_Ntk_t *pNtk, Vec_Ptr_t *vCopies)
Definition: abcUtil.c:617
static int Counter
void Abc_NodeCollectFanins(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition: abcUtil.c:1587
void Abc_NtkCompareCones(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:2086
static Abc_Obj_t * Abc_NtkCreatePi(Abc_Ntk_t *pNtk)
Definition: abc.h:303
static void Vec_IntFreeP(Vec_Int_t **p)
Definition: vecInt.h:289
ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverseNodesContained(Abc_Ntk_t *pNtk, Abc_Obj_t **ppNodes, int nNodes)
Definition: abcDfs.c:298
static void * Vec_AttFree(Vec_Att_t *p, int fFreeMan)
Definition: vecAtt.h:126
void Abc_NtkSetDefaultFxParams(Fxu_Data_t *p)
FUNCTION DEFINITIONS ///.
Definition: abcFxu.c:52
int Abc_NodeFindFanin(Abc_Obj_t *pNode, Abc_Obj_t *pFanin)
Definition: abcUtil.c:758
#define Abc_NtkForEachBox(pNtk, pObj, i)
Definition: abc.h:495
void Abc_NtkDetectMatching(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:1853
static void Vec_PtrWriteEntry(Vec_Ptr_t *p, int i, void *Entry)
Definition: vecPtr.h:396
int Abc_NtkGetBddNodeNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:240
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition: abc.h:461
void Abc_NtkCleanCopy(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:507
void Abc_NtkReverseTopoOrderTest(Abc_Ntk_t *p)
Definition: abcUtil.c:2644
ABC_DLL Vec_Ptr_t * Abc_AigDfs(Abc_Ntk_t *pNtk, int fCollectAll, int fCollectCos)
Definition: abcDfs.c:1014
static int Abc_NtkConstrNum(Abc_Ntk_t *pNtk)
Definition: abc.h:299
void Abc_NtkReverse_rec(Abc_Obj_t *pObj, Vec_Int_t *vVisited)
Definition: abcUtil.c:2633
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
void Abc_NtkCompareSupports(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:2168
void Abc_NtkCleanNext_rec(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:643
Vec_Int_t vFanouts
Definition: abc.h:144
static void * Vec_PtrEntry(Vec_Ptr_t *p, int i)
Definition: vecPtr.h:362
int Abc_NtkGetLitNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:165
double Mio_GateReadArea(Mio_Gate_t *pGate)
Definition: mioApi.c:145
char * pSpec
Definition: abc.h:159
static int Abc_NtkTopoHasBeg(Abc_Obj_t *p)
Definition: abcUtil.c:2575
static int Abc_NodeIsTravIdCurrent(Abc_Obj_t *p)
Definition: abc.h:411
static int Abc_AigNodeIsChoice(Abc_Obj_t *pNode)
Definition: abc.h:398
Abc_Ntk_t * pCopy
Definition: abc.h:204
static Abc_Obj_t * Abc_ObjRegular(Abc_Obj_t *p)
Definition: abc.h:323
int Abc_NtkGetTotalFanins(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:487
Abc_Ntk_t * pNtk
Definition: abc.h:130
unsigned fMarkB
Definition: abc.h:135
void Abc_NodeCollectFanouts(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition: abcUtil.c:1607
static int Vec_IntSize(Vec_Int_t *p)
Definition: bblif.c:252
Abc_Ntk_t * Abc_NtkSopToCubes(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:2539
ABC_DLL void Abc_SopComplement(char *pSop)
Definition: abcSop.c:600
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition: abc.h:526
static Abc_Obj_t * Abc_NtkPo(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:316
void Extra_PrintBinary(FILE *pFile, unsigned Sign[], int nBits)
#define Abc_NtkForEachCi(pNtk, pCi, i)
Definition: abc.h:515
static int Abc_NtkPoNum(Abc_Ntk_t *pNtk)
Definition: abc.h:286
static Vec_Ptr_t * Vec_PtrAlloc(int nCap)
FUNCTION DEFINITIONS ///.
Definition: vecPtr.h:83
Abc_NtkFunc_t ntkFunc
Definition: abc.h:157
int Abc_NtkCrossCut_rec(Abc_Obj_t *pObj, int *pnCutSize, int *pnCutSizeMax)
Definition: abcUtil.c:1962
int Abc_NtkGetChoiceNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:430
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition: abc.h:524
Vec_Ptr_t * Abc_NtkCollectObjects(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:1725
void Abc_NtkOrderCisCos(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:71
static int Abc_NtkIsBddLogic(Abc_Ntk_t *pNtk)
Definition: abc.h:265
#define ABC_FREE(obj)
Definition: abc_global.h:232
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeConst0(Abc_Ntk_t *pNtk)
Definition: abcObj.c:604
void Abc_NodeSopToCubes(Abc_Obj_t *pNodeOld, Abc_Ntk_t *pNtkNew)
Definition: abcUtil.c:2492
int Id
Definition: abc.h:132
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition: abcNames.c:48
int Abc_NodeCompareLevelsIncrease(Abc_Obj_t **pp1, Abc_Obj_t **pp2)
Definition: abcUtil.c:1649
static void Abc_NtkIncrementTravId(Abc_Ntk_t *p)
Definition: abc.h:406
static Abc_Obj_t * Abc_NtkCreateNode(Abc_Ntk_t *pNtk)
Definition: abc.h:308
static int * pSupps
Definition: abcUtil.c:2053
static int Abc_ObjIsNet(Abc_Obj_t *pObj)
Definition: abc.h:354
#define ABC_CALLOC(type, num)
Definition: abc_global.h:230
ABC_DLL Abc_Obj_t * Abc_NtkFetchTwinNode(Abc_Obj_t *pNode)
Definition: abcMap.c:740
static void Abc_ObjXorFaninC(Abc_Obj_t *pObj, int i)
Definition: abc.h:381
ABC_NAMESPACE_IMPL_START void * Abc_NtkAttrFree(Abc_Ntk_t *pNtk, int Attr, int fFreeMan)
DECLARATIONS ///.
Definition: abcUtil.c:50
ABC_DLL int Abc_SopGetVarNum(char *pSop)
Definition: abcSop.c:536
static int Abc_ObjCrossCutInc(Abc_Obj_t *pObj)
Definition: abcUtil.c:1943
static int Abc_ObjIsPo(Abc_Obj_t *pObj)
Definition: abc.h:348
static void Dec_GraphFree(Dec_Graph_t *pGraph)
Definition: dec.h:307
Abc_Obj_t * Abc_NodeRecognizeMux(Abc_Obj_t *pNode, Abc_Obj_t **ppNodeT, Abc_Obj_t **ppNodeE)
Definition: abcUtil.c:1389
Abc_Obj_t * pNext
Definition: abc.h:131
void Io_WriteBlifLogic(Abc_Ntk_t *pNtk, char *pFileName, int fWriteLatches)
FUNCTION DEFINITIONS ///.
Definition: ioWriteBlif.c:59
#define assert(ex)
Definition: util_old.h:213
static void Vec_PtrClear(Vec_Ptr_t *p)
Definition: vecPtr.h:545
void Abc_NtkReassignIds(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:1769
static int Abc_NtkTopoHasEnd(Abc_Obj_t *p)
Definition: abcUtil.c:2576
static Abc_Obj_t * Abc_ObjNot(Abc_Obj_t *p)
Definition: abc.h:324
void Abc_NtkReverseTopoOrder_rec(Abc_Obj_t *pObj, int fThisIsPivot)
Definition: abcUtil.c:2581
int Abc_CountZddCubes(DdManager *dd, DdNode *zCover)
Definition: abcFunc.c:593
int Abc_NtkCompareConesCompare(int *pNum1, int *pNum2)
Definition: abcUtil.c:2066
static Abc_Ntk_t * Abc_ObjNtk(Abc_Obj_t *pObj)
Definition: abc.h:334
void * pData
Definition: abc.h:145
ABC_DLL Vec_Ptr_t * Abc_NtkDfsNodes(Abc_Ntk_t *pNtk, Abc_Obj_t **ppNodes, int nNodes)
Definition: abcDfs.c:120
static int Abc_ObjFaninId1(Abc_Obj_t *pObj)
Definition: abc.h:368
unsigned fExor
Definition: abc.h:138
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
#define Abc_NtkForEachPo(pNtk, pPo, i)
Definition: abc.h:517
int Abc_NodeCompareLevelsDecrease(Abc_Obj_t **pp1, Abc_Obj_t **pp2)
Definition: abcUtil.c:1675
static Abc_Obj_t * Abc_ObjFanout(Abc_Obj_t *pObj, int i)
Definition: abc.h:370
static Abc_Obj_t * Abc_ObjFanin(Abc_Obj_t *pObj, int i)
Definition: abc.h:372
static void Vec_IntFree(Vec_Int_t *p)
Definition: bblif.c:235
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition: vecPtr.h:55
void Abc_NtkFillTemp(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:553
static int Abc_ObjIsComplement(Abc_Obj_t *p)
Definition: abc.h:322
static void Vec_IntClear(Vec_Int_t *p)
Definition: bblif.c:452
ABC_INT64_T abctime
Definition: abc_global.h:278
#define Abc_NtkForEachObj(pNtk, pObj, i)
ITERATORS ///.
Definition: abc.h:446
static int Abc_NtkObjNum(Abc_Ntk_t *pNtk)
Definition: abc.h:283
ABC_DLL int Abc_NtkLevel(Abc_Ntk_t *pNtk)
Definition: abcDfs.c:1265
ABC_DLL void Abc_NtkAddDummyPiNames(Abc_Ntk_t *pNtk)
Definition: abcNames.c:378
ABC_DLL void Abc_NodeComplement(Abc_Obj_t *pNode)
Definition: abcObj.c:980
void Abc_NtkCleanMarkB(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:682
Abc_Ntk_t * Abc_NtkAddBuffs(Abc_Ntk_t *pNtkInit, int fDirect, int fReverse, int nImprove, int fVerbose)
Definition: abcUtil.c:2416
static Abc_Obj_t * Abc_NtkCreatePo(Abc_Ntk_t *pNtk)
Definition: abc.h:304
static Abc_Obj_t * Abc_ObjChild1(Abc_Obj_t *pObj)
Definition: abc.h:384
static void ** Vec_PtrArray(Vec_Ptr_t *p)
Definition: vecPtr.h:279
ABC_DLL int Abc_SopIsComplement(char *pSop)
Definition: abcSop.c:655
void Abc_NtkCleanData(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:534
float Abc_NtkComputeDelay(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:2448
ABC_DLL char * Abc_SopCreateOr(Mem_Flex_t *pMan, int nVars, int *pfCompl)
Definition: abcSop.c:206
char * pName
Definition: abc.h:158
int Abc_NodeIsMuxControlType(Abc_Obj_t *pNode)
Definition: abcUtil.c:1357
int Abc_NtkGetMultiRefNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:218
int Abc_NtkGetAigNodeNum(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:266
Abc_NtkType_t ntkType
Definition: abc.h:156
static Abc_Obj_t * Abc_ObjFanout0(Abc_Obj_t *pObj)
Definition: abc.h:371
Abc_Ntk_t * Abc_NtkAddBuffsInt(Abc_Ntk_t *pNtkInit, int fReverse, int nImprove, int fVerbose)
Definition: abcUtil.c:2306
int nTotal
DECLARATIONS ///.
Definition: cutTruth.c:37
#define Abc_NtkForEachPi(pNtk, pPi, i)
Definition: abc.h:513
ABC_DLL void Abc_NodeComplementInput(Abc_Obj_t *pNode, Abc_Obj_t *pFanin)
Definition: abcObj.c:1005
Vec_Int_t * Abc_NtkGetCiIds(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:1747
static void Abc_NodeSetTravIdCurrent(Abc_Obj_t *p)
Definition: abc.h:409
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
int Abc_NodeIsExorType(Abc_Obj_t *pNode)
Definition: abcUtil.c:1259
static void Vec_PtrFree(Vec_Ptr_t *p)
Definition: vecPtr.h:223
void Abc_NtkTransferCopy(Abc_Ntk_t *pNtk)
Definition: abcUtil.c:1922