ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
abcDfs.c
Go to the documentation of this file.
1
20
21#include "abc.h"
22#include "proof/cec/cec.h"
23
25
26
30
34
46void Abc_NtkDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
47{
48 Abc_Obj_t * pFanin;
49 int i;
50 assert( !Abc_ObjIsNet(pNode) );
51 // if this node is already visited, skip
52 if ( Abc_NodeIsTravIdCurrent( pNode ) )
53 return;
54 // mark the node as visited
55 Abc_NodeSetTravIdCurrent( pNode );
56 // skip the CI
57 if ( Abc_ObjIsCi(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
58 return;
59 assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
60 // visit the transitive fanin of the node
61 Abc_ObjForEachFanin( pNode, pFanin, i )
62 {
63// pFanin = Abc_ObjFanin( pNode, Abc_ObjFaninNum(pNode)-1-i );
64 Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(pFanin), vNodes );
65 }
66 // add the node after the fanins have been added
67 Vec_PtrPush( vNodes, pNode );
68}
69
82Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll )
83{
84 Vec_Ptr_t * vNodes;
85 Abc_Obj_t * pObj;
86 int i;
87 // set the traversal ID
88 Abc_NtkIncrementTravId( pNtk );
89 // start the array of nodes
90 vNodes = Vec_PtrAlloc( 100 );
91 if ( pNtk->nBarBufs2 > 0 )
92 {
93 Abc_NtkForEachBarBuf( pNtk, pObj, i )
94 {
95 Abc_NodeSetTravIdCurrent( pObj );
96 Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(Abc_ObjFanin0(pObj)), vNodes );
97 Vec_PtrPush( vNodes, pObj );
98 }
99 }
100 Abc_NtkForEachCo( pNtk, pObj, i )
101 {
102 Abc_NodeSetTravIdCurrent( pObj );
103 Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(Abc_ObjFanin0(pObj)), vNodes );
104 }
105 // collect dangling nodes if asked to
106 if ( fCollectAll )
107 {
108 Abc_NtkForEachNode( pNtk, pObj, i )
109 if ( !Abc_NodeIsTravIdCurrent(pObj) )
110 Abc_NtkDfs_rec( pObj, vNodes );
111 }
112 return vNodes;
113}
114
128{
129 Vec_Ptr_t * vNodes = Vec_PtrAlloc( 100 );
130 Abc_Obj_t * pObj; int i;
131 Abc_NtkIncrementTravId( pNtk );
132 Abc_NtkForEachCo( pNtk, pObj, i )
133 {
134 Abc_NodeSetTravIdCurrent( pObj );
135 Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(Abc_ObjFanin0(pObj)), vNodes );
136 }
137 return vNodes;
138}
139
151Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes )
152{
153 Vec_Ptr_t * vNodes;
154 int i;
155 // set the traversal ID
156 Abc_NtkIncrementTravId( pNtk );
157 // start the array of nodes
158 vNodes = Vec_PtrAlloc( 100 );
159 // go through the PO nodes and call for each of them
160 for ( i = 0; i < nNodes; i++ )
161 {
162 if ( Abc_NtkIsStrash(pNtk) && Abc_AigNodeIsConst(ppNodes[i]) )
163 continue;
164 if ( Abc_ObjIsCo(ppNodes[i]) )
165 {
166 Abc_NodeSetTravIdCurrent(ppNodes[i]);
167 Abc_NtkDfs_rec( Abc_ObjFanin0Ntk(Abc_ObjFanin0(ppNodes[i])), vNodes );
168 }
169 else if ( Abc_ObjIsNode(ppNodes[i]) || Abc_ObjIsCi(ppNodes[i]) )
170 Abc_NtkDfs_rec( ppNodes[i], vNodes );
171 }
172 return vNodes;
173}
174
175
188{
189 Abc_Obj_t * pFanout;
190 int i;
191 assert( !Abc_ObjIsNet(pNode) );
192 // if this node is already visited, skip
193 if ( Abc_NodeIsTravIdCurrent( pNode ) )
194 return;
195 // mark the node as visited
196 Abc_NodeSetTravIdCurrent( pNode );
197 // skip the CI
198 if ( Abc_ObjIsCo(pNode) )
199 return;
200 assert( Abc_ObjIsNode( pNode ) );
201 // visit the transitive fanin of the node
202 pNode = Abc_ObjFanout0Ntk(pNode);
203 Abc_ObjForEachFanout( pNode, pFanout, i )
204 Abc_NtkDfsReverse_rec( pFanout, vNodes );
205 // add the node after the fanins have been added
206 Vec_PtrPush( vNodes, pNode );
207}
208
222{
223 Vec_Ptr_t * vNodes;
224 Abc_Obj_t * pObj, * pFanout;
225 int i, k;
226 // set the traversal ID
227 Abc_NtkIncrementTravId( pNtk );
228 // start the array of nodes
229 vNodes = Vec_PtrAlloc( 100 );
230 Abc_NtkForEachCi( pNtk, pObj, i )
231 {
232 Abc_NodeSetTravIdCurrent( pObj );
233 pObj = Abc_ObjFanout0Ntk(pObj);
234 Abc_ObjForEachFanout( pObj, pFanout, k )
235 Abc_NtkDfsReverse_rec( pFanout, vNodes );
236 }
237 // add constant nodes in the end
238 if ( !Abc_NtkIsStrash(pNtk) ) {
239 Abc_NtkForEachNode( pNtk, pObj, i )
240 if ( Abc_NodeIsConst(pObj) )
241 Vec_PtrPush( vNodes, pObj );
242 }
243 return vNodes;
244}
245
258{
259 Abc_Obj_t * pFanout;
260 int i;
261 assert( !Abc_ObjIsNet(pNode) );
262 // if this node is already visited, skip
263 if ( Abc_NodeIsTravIdCurrent( pNode ) )
264 return;
265 // mark the node as visited
266 Abc_NodeSetTravIdCurrent( pNode );
267 // skip the CI
268 if ( Abc_ObjIsCo(pNode) )
269 return;
270 assert( Abc_ObjIsNode( pNode ) );
271 // visit the transitive fanin of the node
272 pNode = Abc_ObjFanout0Ntk(pNode);
273 Abc_ObjForEachFanout( pNode, pFanout, i )
274 Abc_NtkDfsReverseNodes_rec( pFanout, vNodes );
275 // add the node after the fanins have been added
276// Vec_PtrPush( vNodes, pNode );
277 Vec_PtrFillExtra( vNodes, pNode->Level + 1, NULL );
278 pNode->pCopy = (Abc_Obj_t *)Vec_PtrEntry( vNodes, pNode->Level );
279 Vec_PtrWriteEntry( vNodes, pNode->Level, pNode );
280}
281
294Vec_Ptr_t * Abc_NtkDfsReverseNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes )
295{
296 Vec_Ptr_t * vNodes;
297 Abc_Obj_t * pObj, * pFanout;
298 int i, k;
299 assert( Abc_NtkIsStrash(pNtk) );
300 // set the traversal ID
301 Abc_NtkIncrementTravId( pNtk );
302 // start the array of nodes
303 vNodes = Vec_PtrStart( Abc_AigLevel(pNtk) + 1 );
304 for ( i = 0; i < nNodes; i++ )
305 {
306 pObj = ppNodes[i];
307 assert( Abc_ObjIsCi(pObj) );
308 Abc_NodeSetTravIdCurrent( pObj );
309 pObj = Abc_ObjFanout0Ntk(pObj);
310 Abc_ObjForEachFanout( pObj, pFanout, k )
311 Abc_NtkDfsReverseNodes_rec( pFanout, vNodes );
312 }
313 return vNodes;
314}
315
330{
331 Vec_Ptr_t * vNodes;
332 Abc_Obj_t * pObj, * pFanout, * pFanin;
333 int i, k, m, nLevels;
334 // set the levels
335 nLevels = Abc_NtkLevel( pNtk );
336 // set the traversal ID
337 Abc_NtkIncrementTravId( pNtk );
338 // start the array of nodes
339 vNodes = Vec_PtrStart( nLevels + 2 );
340 for ( i = 0; i < nNodes; i++ )
341 {
342 pObj = ppNodes[i];
343 assert( Abc_ObjIsCi(pObj) );
344 Abc_NodeSetTravIdCurrent( pObj );
345 // add to the array
346 assert( pObj->Level == 0 );
347 pObj->pCopy = (Abc_Obj_t *)Vec_PtrEntry( vNodes, pObj->Level );
348 Vec_PtrWriteEntry( vNodes, pObj->Level, pObj );
349 }
350 // iterate through the levels
351 for ( i = 0; i <= nLevels; i++ )
352 {
353 // iterate through the nodes on each level
354 for ( pObj = (Abc_Obj_t *)Vec_PtrEntry(vNodes, i); pObj; pObj = pObj->pCopy )
355 {
356 // iterate through the fanouts of each node
357 Abc_ObjForEachFanout( pObj, pFanout, k )
358 {
359 // skip visited nodes
360 if ( Abc_NodeIsTravIdCurrent(pFanout) )
361 continue;
362 // visit the fanins of this fanout
363 Abc_ObjForEachFanin( pFanout, pFanin, m )
364 {
365 if ( !Abc_NodeIsTravIdCurrent(pFanin) )
366 break;
367 }
368 if ( m < Abc_ObjFaninNum(pFanout) )
369 continue;
370 // all fanins are already collected
371
372 // mark the node as visited
373 Abc_NodeSetTravIdCurrent( pFanout );
374 // handle the COs
375 if ( Abc_ObjIsCo(pFanout) )
376 pFanout->Level = nLevels + 1;
377 // add to the array
378 pFanout->pCopy = (Abc_Obj_t *)Vec_PtrEntry( vNodes, pFanout->Level );
379 Vec_PtrWriteEntry( vNodes, pFanout->Level, pFanout );
380 // handle the COs
381 if ( Abc_ObjIsCo(pFanout) )
382 pFanout->Level = 0;
383 }
384 }
385 }
386 return vNodes;
387}
388
389
401void Abc_NtkDfsSeq_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
402{
403 Abc_Obj_t * pFanin;
404 int i;
405 // if this node is already visited, skip
406 if ( Abc_NodeIsTravIdCurrent( pNode ) )
407 return;
408 // mark the node as visited
409 Abc_NodeSetTravIdCurrent( pNode );
410 // visit the transitive fanin of the node
411 Abc_ObjForEachFanin( pNode, pFanin, i )
412 Abc_NtkDfsSeq_rec( pFanin, vNodes );
413 // add the node after the fanins have been added
414 Vec_PtrPush( vNodes, pNode );
415}
416
429{
430 Vec_Ptr_t * vNodes;
431 Abc_Obj_t * pObj;
432 int i;
433 assert( !Abc_NtkIsNetlist(pNtk) );
434 // set the traversal ID
435 Abc_NtkIncrementTravId( pNtk );
436 // start the array of nodes
437 vNodes = Vec_PtrAlloc( 100 );
438 Abc_NtkForEachPo( pNtk, pObj, i )
439 Abc_NtkDfsSeq_rec( pObj, vNodes );
440 // mark the PIs
441 Abc_NtkForEachPi( pNtk, pObj, i )
442 Abc_NtkDfsSeq_rec( pObj, vNodes );
443 return vNodes;
444}
445
446
459{
460 Abc_Obj_t * pFanout;
461 int i;
462 // if this node is already visited, skip
463 if ( Abc_NodeIsTravIdCurrent( pNode ) )
464 return;
465 // mark the node as visited
466 Abc_NodeSetTravIdCurrent( pNode );
467 // visit the transitive fanin of the node
468 Abc_ObjForEachFanout( pNode, pFanout, i )
469 Abc_NtkDfsSeqReverse_rec( pFanout, vNodes );
470 // add the node after the fanins have been added
471 Vec_PtrPush( vNodes, pNode );
472}
473
486{
487 Vec_Ptr_t * vNodes;
488 Abc_Obj_t * pObj;
489 int i;
490 assert( !Abc_NtkIsNetlist(pNtk) );
491 // set the traversal ID
492 Abc_NtkIncrementTravId( pNtk );
493 // start the array of nodes
494 vNodes = Vec_PtrAlloc( 100 );
495 Abc_NtkForEachPi( pNtk, pObj, i )
496 Abc_NtkDfsSeqReverse_rec( pObj, vNodes );
497 // mark the logic feeding into POs
498 Abc_NtkForEachPo( pNtk, pObj, i )
499 Abc_NtkDfsSeq_rec( pObj, vNodes );
500 return vNodes;
501}
502
503
515void Abc_NtkDfs_iter( Vec_Ptr_t * vStack, Abc_Obj_t * pRoot, Vec_Ptr_t * vNodes )
516{
517 Abc_Obj_t * pNode, * pFanin;
518 int iFanin;
519 // if this node is already visited, skip
520 if ( Abc_NodeIsTravIdCurrent( pRoot ) )
521 return;
522 // mark the node as visited
523 Abc_NodeSetTravIdCurrent( pRoot );
524 // skip the CI
525 if ( Abc_ObjIsCi(pRoot) || (Abc_NtkIsStrash(pRoot->pNtk) && Abc_AigNodeIsConst(pRoot)) )
526 return;
527 // add the CI
528 Vec_PtrClear( vStack );
529 Vec_PtrPush( vStack, pRoot );
530 Vec_PtrPush( vStack, (void *)0 );
531 while ( Vec_PtrSize(vStack) > 0 )
532 {
533 // get the node and its fanin
534 iFanin = (int)(ABC_PTRINT_T)Vec_PtrPop(vStack);
535 pNode = (Abc_Obj_t *)Vec_PtrPop(vStack);
536 assert( !Abc_ObjIsNet(pNode) );
537 // add it to the array of nodes if we finished
538 if ( iFanin == Abc_ObjFaninNum(pNode) )
539 {
540 Vec_PtrPush( vNodes, pNode );
541 continue;
542 }
543 // explore the next fanin
544 Vec_PtrPush( vStack, pNode );
545 Vec_PtrPush( vStack, (void *)(ABC_PTRINT_T)(iFanin+1) );
546 // get the fanin
547 pFanin = Abc_ObjFanin0Ntk( Abc_ObjFanin(pNode,iFanin) );
548 // if this node is already visited, skip
549 if ( Abc_NodeIsTravIdCurrent( pFanin ) )
550 continue;
551 // mark the node as visited
552 Abc_NodeSetTravIdCurrent( pFanin );
553 // skip the CI
554 if ( Abc_ObjIsCi(pFanin) || (Abc_NtkIsStrash(pFanin->pNtk) && Abc_AigNodeIsConst(pFanin)) )
555 continue;
556 Vec_PtrPush( vStack, pFanin );
557 Vec_PtrPush( vStack, (void *)0 );
558 }
559}
560
573Vec_Ptr_t * Abc_NtkDfsIter( Abc_Ntk_t * pNtk, int fCollectAll )
574{
575 Vec_Ptr_t * vNodes, * vStack;
576 Abc_Obj_t * pObj;
577 int i;
578 // set the traversal ID
579 Abc_NtkIncrementTravId( pNtk );
580 // start the array of nodes
581 vNodes = Vec_PtrAlloc( 1000 );
582 vStack = Vec_PtrAlloc( 1000 );
583 Abc_NtkForEachCo( pNtk, pObj, i )
584 {
585 Abc_NodeSetTravIdCurrent( pObj );
586 Abc_NtkDfs_iter( vStack, Abc_ObjFanin0Ntk(Abc_ObjFanin0(pObj)), vNodes );
587 }
588 // collect dangling nodes if asked to
589 if ( fCollectAll )
590 {
591 Abc_NtkForEachNode( pNtk, pObj, i )
592 if ( !Abc_NodeIsTravIdCurrent(pObj) )
593 Abc_NtkDfs_iter( vStack, pObj, vNodes );
594 }
595 Vec_PtrFree( vStack );
596 return vNodes;
597}
598
612{
613 Vec_Ptr_t * vNodes, * vStack;
614 Abc_Obj_t * pObj;
615 int i;
616 Abc_NtkIncrementTravId( pNtk );
617 vNodes = Vec_PtrAlloc( 1000 );
618 vStack = Vec_PtrAlloc( 1000 );
619 Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i )
620 if ( !Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pObj)) )
621 Abc_NtkDfs_iter( vStack, Abc_ObjRegular(pObj), vNodes );
622 Vec_PtrFree( vStack );
623 return vNodes;
624}
625
626
638void Abc_NtkDfsHie_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vNodes )
639{
640 Abc_Obj_t * pFanin;
641 int i;
642 // if this node is already visited, skip
643 if ( Abc_NodeIsTravIdCurrent( pObj ) )
644 return;
645 // mark the node as visited
646 Abc_NodeSetTravIdCurrent( pObj );
647 // visit the transitive fanin of the node
648 Abc_ObjForEachFanin( pObj, pFanin, i )
649 Abc_NtkDfsHie_rec( pFanin, vNodes );
650 // add the node after the fanins have been added
651 Vec_PtrPush( vNodes, pObj );
652}
653
665Vec_Ptr_t * Abc_NtkDfsHie( Abc_Ntk_t * pNtk, int fCollectAll )
666{
667 Vec_Ptr_t * vNodes;
668 Abc_Obj_t * pObj;
669 int i;
670 // set the traversal ID
671 Abc_NtkIncrementTravId( pNtk );
672 // start the array of nodes
673 vNodes = Vec_PtrAlloc( 100 );
674 Abc_NtkForEachPo( pNtk, pObj, i )
675 Abc_NtkDfsHie_rec( pObj, vNodes );
676 // collect dangling nodes if asked to
677 if ( fCollectAll )
678 {
679 Abc_NtkForEachObj( pNtk, pObj, i )
680 if ( !Abc_NodeIsTravIdCurrent(pObj) )
681 Abc_NtkDfs_rec( pObj, vNodes );
682 }
683 return vNodes;
684}
685
686
699{
700 Abc_Obj_t * pNode, * pFanin;
701 int i, k;
702 // set the traversal ID
703 Abc_NtkIncrementTravId( pNtk );
704 // mark the CIs
705 Abc_NtkForEachCi( pNtk, pNode, i )
706 Abc_NodeSetTravIdCurrent( pNode );
707 // go through the nodes
708 Abc_NtkForEachNode( pNtk, pNode, i )
709 {
710 // check the fanins of the node
711 Abc_ObjForEachFanin( pNode, pFanin, k )
712 if ( !Abc_NodeIsTravIdCurrent(pFanin) )
713 return 0;
714 // check the choices of the node
715 if ( Abc_NtkIsStrash(pNtk) && Abc_AigNodeIsChoice(pNode) )
716 for ( pFanin = (Abc_Obj_t *)pNode->pData; pFanin; pFanin = (Abc_Obj_t *)pFanin->pData )
717 if ( !Abc_NodeIsTravIdCurrent(pFanin) )
718 return 0;
719 // mark the node as visited
720 Abc_NodeSetTravIdCurrent( pNode );
721 }
722 return 1;
723}
724
737{
738 Abc_Obj_t * pNext;
739 Abc_Obj_t * pNode; int i;
740 assert( Abc_ObjIsNet(pNet) );
741 if ( Abc_NodeIsTravIdCurrent( pNet ) )
742 return;
743 Abc_NodeSetTravIdCurrent( pNet );
744 pNode = Abc_ObjFanin0( pNet );
745 Abc_ObjForEachFanin( pNode, pNext, i )
746 Abc_NtkDfsNets_rec( pNext, vNets );
747 Abc_ObjForEachFanout( pNode, pNext, i )
748 Vec_PtrPush( vNets, pNext );
749}
751{
752 Vec_Ptr_t * vNets;
753 Abc_Obj_t * pObj; int i;
754 vNets = Vec_PtrAlloc( 100 );
755 Abc_NtkIncrementTravId( pNtk );
756 Abc_NtkForEachCi( pNtk, pObj, i )
757 Abc_NodeSetTravIdCurrent( Abc_ObjFanout0(pObj) );
758 Abc_NtkForEachCi( pNtk, pObj, i )
759 Vec_PtrPush( vNets, Abc_ObjFanout0(pObj) );
760 Abc_NtkForEachCo( pNtk, pObj, i )
761 Abc_NtkDfsNets_rec( Abc_ObjFanin0(pObj), vNets );
762 return vNets;
763}
764
778{
779 Abc_Obj_t * pFanin;
780 int i;
781 assert( !Abc_ObjIsNet(pNode) );
782 if ( Abc_ObjIsBo(pNode) )
783 pNode = Abc_ObjFanin0(pNode);
784 if ( Abc_ObjIsPi(pNode) )
785 return;
786 assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
787 if ( Abc_NodeIsTravIdCurrent( pNode ) )
788 return;
789 Abc_NodeSetTravIdCurrent( pNode );
790 Abc_ObjForEachFanin( pNode, pFanin, i )
791 {
792 if ( Abc_ObjIsBox(pNode) )
793 pFanin = Abc_ObjFanin0(pFanin);
794 assert( Abc_ObjIsNet(pFanin) );
795 Abc_NtkDfsWithBoxes_rec( Abc_ObjFanin0Ntk(pFanin), vNodes );
796 }
797 Vec_PtrPush( vNodes, pNode );
798}
800{
801 Vec_Ptr_t * vNodes;
802 Abc_Obj_t * pObj;
803 int i;
804 Abc_NtkIncrementTravId( pNtk );
805 vNodes = Vec_PtrAlloc( 100 );
806 Abc_NtkForEachPo( pNtk, pObj, i )
807 {
808 assert( Abc_ObjIsNet(Abc_ObjFanin0(pObj)) );
809 Abc_NtkDfsWithBoxes_rec( Abc_ObjFanin0Ntk(Abc_ObjFanin0(pObj)), vNodes );
810 }
811 return vNodes;
812}
813
814
827{
828 Abc_Obj_t * pFanin;
829 int i;
830 assert( !Abc_ObjIsNet(pNode) );
831 // if this node is already visited, skip
832 if ( Abc_NodeIsTravIdCurrent( pNode ) )
833 return;
834 // mark the node as visited
835 Abc_NodeSetTravIdCurrent( pNode );
836 // collect the CI
837 if ( Abc_ObjIsCi(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_ObjFaninNum(pNode) == 0) )
838 {
839 Vec_PtrPush( vNodes, pNode );
840 return;
841 }
842 assert( Abc_ObjIsNode( pNode ) );
843 // visit the transitive fanin of the node
844 Abc_ObjForEachFanin( pNode, pFanin, i )
845 Abc_NtkNodeSupport_rec( Abc_ObjFanin0Ntk(pFanin), vNodes );
846}
847
860{
861 Vec_Ptr_t * vNodes;
862 Abc_Obj_t * pNode;
863 int i;
864 // set the traversal ID
865 Abc_NtkIncrementTravId( pNtk );
866 // start the array of nodes
867 vNodes = Vec_PtrAlloc( 100 );
868 // go through the PO nodes and call for each of them
869 Abc_NtkForEachCo( pNtk, pNode, i )
870 Abc_NtkNodeSupport_rec( Abc_ObjFanin0(pNode), vNodes );
871 // add unused CIs
872 Abc_NtkForEachCi( pNtk, pNode, i )
873 if ( !Abc_NodeIsTravIdCurrent( pNode ) )
874 Vec_PtrPush( vNodes, pNode );
875 assert( Vec_PtrSize(vNodes) == Abc_NtkCiNum(pNtk) );
876 return vNodes;
877}
878
890Vec_Ptr_t * Abc_NtkNodeSupport( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes )
891{
892 Vec_Ptr_t * vNodes;
893 int i;
894 // set the traversal ID
895 Abc_NtkIncrementTravId( pNtk );
896 // start the array of nodes
897 vNodes = Vec_PtrAlloc( 100 );
898 // go through the PO nodes and call for each of them
899 for ( i = 0; i < nNodes; i++ )
900 if ( Abc_ObjIsCo(ppNodes[i]) && Abc_ObjFaninNum(Abc_ObjFanin0(ppNodes[i])) != 0 )
901 Abc_NtkNodeSupport_rec( Abc_ObjFanin0(ppNodes[i]), vNodes );
902 else if ( !Abc_ObjIsCo(ppNodes[i]) && Abc_ObjFaninNum(ppNodes[i]) != 0 )
903 Abc_NtkNodeSupport_rec( ppNodes[i], vNodes );
904 return vNodes;
905}
906
919{
920 Abc_Obj_t * pFanin;
921 int i;
922 assert( !Abc_ObjIsNet(pNode) );
923 // if this node is already visited, skip
924 if ( Abc_NodeIsTravIdCurrent( pNode ) )
925 return;
926 // mark the node as visited
927 Abc_NodeSetTravIdCurrent( pNode );
928 // collect the CI
929 if ( Abc_ObjIsCi(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_ObjFaninNum(pNode) == 0) )
930 {
931 if ( Abc_ObjIsCi(pNode) )
932 Vec_IntPush( vNodes, pNode->iTemp );
933 return;
934 }
935 assert( Abc_ObjIsNode( pNode ) );
936 // visit the transitive fanin of the node
937 Abc_ObjForEachFanin( pNode, pFanin, i )
938 Abc_NtkNodeSupportInt_rec( Abc_ObjFanin0Ntk(pFanin), vNodes );
939}
941{
942 Vec_Int_t * vNodes;
943 Abc_Obj_t * pObj;
944 int i;
945 if ( iCo < 0 || iCo >= Abc_NtkCoNum(pNtk) )
946 return NULL;
947 // save node indices in the CI nodes
948 Abc_NtkForEachCi( pNtk, pObj, i )
949 pObj->iTemp = i;
950 // collect the indexes of CI nodes in the TFI of the CO node
951 Abc_NtkIncrementTravId( pNtk );
952 pObj = Abc_NtkCo( pNtk, iCo );
953 vNodes = Vec_IntAlloc( 100 );
954 Abc_NtkNodeSupportInt_rec( Abc_ObjFanin0(pObj), vNodes );
955 Vec_IntSort( vNodes, 0 );
956 return vNodes;
957}
958
971{
972 int iLit0, iLit1;
973 if ( Abc_NodeIsTravIdCurrent(pNode) || Abc_ObjFaninNum(pNode) == 0 || Abc_ObjIsCi(pNode) )
974 return pNode->iTemp;
975 assert( Abc_ObjIsNode( pNode ) );
976 Abc_NodeSetTravIdCurrent( pNode );
977 iLit0 = Abc_NtkFunctionalIsoGia_rec( pNew, Abc_ObjFanin0(pNode) );
978 iLit1 = Abc_NtkFunctionalIsoGia_rec( pNew, Abc_ObjFanin1(pNode) );
979 iLit0 = Abc_LitNotCond( iLit0, Abc_ObjFaninC0(pNode) );
980 iLit1 = Abc_LitNotCond( iLit1, Abc_ObjFaninC1(pNode) );
981 return (pNode->iTemp = Gia_ManHashAnd(pNew, iLit0, iLit1));
982}
983Gia_Man_t * Abc_NtkFunctionalIsoGia( Abc_Ntk_t * pNtk, int iCo1, int iCo2, int fCommon )
984{
985 Gia_Man_t * pNew = NULL, * pTemp;
986 Vec_Int_t * vSupp1 = Abc_NtkNodeSupportInt( pNtk, iCo1 );
987 Vec_Int_t * vSupp2 = Abc_NtkNodeSupportInt( pNtk, iCo2 );
988 if ( Vec_IntSize(vSupp1) == Vec_IntSize(vSupp2) )
989 {
990 Abc_Obj_t * pObj;
991 int i, iCi, iLit1, iLit2;
992 pNew = Gia_ManStart( 1000 );
993 pNew->pName = Abc_UtilStrsav( pNtk->pName );
994 pNew->pSpec = Abc_UtilStrsav( pNtk->pSpec );
995 Gia_ManHashStart( pNew );
996 // put commom together
997 if ( fCommon )
998 {
999 Vec_Int_t * vCommon = Vec_IntAlloc( Vec_IntSize(vSupp1) );
1000 Vec_IntTwoRemoveCommon( vSupp1, vSupp2, vCommon );
1001 Vec_IntAppend( vSupp1, vCommon );
1002 Vec_IntAppend( vSupp2, vCommon );
1003 Vec_IntFree( vCommon );
1004 assert( Vec_IntSize(vSupp1) == Vec_IntSize(vSupp2) );
1005 }
1006 // primary inputs
1007 Abc_AigConst1(pNtk)->iTemp = 1;
1008 Vec_IntForEachEntry( vSupp1, iCi, i )
1009 Abc_NtkCi(pNtk, iCi)->iTemp = Gia_ManAppendCi(pNew);
1010 // create the first cone
1011 Abc_NtkIncrementTravId( pNtk );
1012 pObj = Abc_NtkCo( pNtk, iCo1 );
1013 iLit1 = Abc_NtkFunctionalIsoGia_rec( pNew, Abc_ObjFanin0(pObj) );
1014 iLit1 = Abc_LitNotCond( iLit1, Abc_ObjFaninC0(pObj) );
1015 // primary inputs
1016 Vec_IntForEachEntry( vSupp2, iCi, i )
1017 Abc_NtkCi(pNtk, iCi)->iTemp = Gia_ManCiLit(pNew, i);
1018 // create the second cone
1019 Abc_NtkIncrementTravId( pNtk );
1020 pObj = Abc_NtkCo( pNtk, iCo2 );
1021 iLit2 = Abc_NtkFunctionalIsoGia_rec( pNew, Abc_ObjFanin0(pObj) );
1022 iLit2 = Abc_LitNotCond( iLit2, Abc_ObjFaninC0(pObj) );
1023 Gia_ManAppendCo( pNew, iLit1 );
1024 Gia_ManAppendCo( pNew, iLit2 );
1025 // perform cleanup
1026 pNew = Gia_ManCleanup( pTemp = pNew );
1027 Gia_ManStop( pTemp );
1028 }
1029 Vec_IntFree( vSupp1 );
1030 Vec_IntFree( vSupp2 );
1031 return pNew;
1032}
1033int Abc_NtkFunctionalIsoInt( Abc_Ntk_t * pNtk, int iCo1, int iCo2, int fCommon )
1034{
1035 Gia_Man_t * pGia; int Value;
1036 assert( Abc_NtkIsStrash(pNtk) );
1037 if ( iCo1 < 0 || iCo1 >= Abc_NtkCoNum(pNtk) )
1038 return 0;
1039 if ( iCo2 < 0 || iCo2 >= Abc_NtkCoNum(pNtk) )
1040 return 0;
1041 pGia = Abc_NtkFunctionalIsoGia( pNtk, iCo1, iCo2, fCommon );
1042 if ( pGia == NULL )
1043 return 0;
1044 Value = Cec_ManVerifySimple( pGia );
1045 Gia_ManStop( pGia );
1046 return (int)(Value == 1);
1047}
1048int Abc_NtkFunctionalIso( Abc_Ntk_t * pNtk, int iCo1, int iCo2, int fCommon )
1049{
1050 Abc_Ntk_t * pNtkNew; int Result;
1051 if ( Abc_NtkIsStrash(pNtk) )
1052 return Abc_NtkFunctionalIsoInt( pNtk, iCo1, iCo2, fCommon );
1053 pNtkNew = Abc_NtkStrash( pNtk, 0, 0, 0 );
1054 Result = Abc_NtkFunctionalIsoInt( pNtkNew, iCo1, iCo2, fCommon );
1055 Abc_NtkDelete( pNtkNew );
1056 return Result;
1057}
1058
1059
1072{
1073 Abc_Obj_t * pFanin;
1074 int i, Counter = 0;
1075 if ( Abc_NodeIsTravIdCurrent(pObj) )
1076 return 0;
1077 Abc_NodeSetTravIdCurrent(pObj);
1078 if ( Abc_ObjIsPi(pObj) )
1079 return 1;
1080 assert( Abc_ObjIsNode(pObj) || Abc_ObjIsBox(pObj) );
1081 Abc_ObjForEachFanin( pObj, pFanin, i )
1082 Counter += Abc_ObjSuppSize_rec( pFanin );
1083 return Counter;
1084}
1085
1097{
1098 Abc_NtkIncrementTravId( Abc_ObjNtk(pObj) );
1099 return Abc_ObjSuppSize_rec( pObj );
1100}
1101
1113{
1114 Abc_Obj_t * pObj;
1115 int i, Counter = 0;
1116 abctime clk = Abc_Clock();
1117 Abc_NtkForEachObj( p, pObj, i )
1118 if ( Abc_ObjIsNode(pObj) )
1119 Counter += (Abc_ObjSuppSize(pObj) <= 16);
1120 printf( "Nodes with small support %d (out of %d)\n", Counter, Abc_NtkNodeNum(p) );
1121 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
1122 return Counter;
1123}
1124
1137{
1138 Vec_Ptr_t * vSupp;
1139 Abc_Obj_t * pObj;
1140 int i, nTotalSupps = 0;
1141 Abc_NtkForEachCo( pNtk, pObj, i )
1142 {
1143 vSupp = Abc_NtkNodeSupport( pNtk, &pObj, 1 );
1144 nTotalSupps += Vec_PtrSize( vSupp );
1145 Vec_PtrFree( vSupp );
1146 }
1147 printf( "Total supports = %d.\n", nTotalSupps );
1148}
1149
1150
1162void Abc_AigDfs_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes )
1163{
1164 Abc_Obj_t * pFanin;
1165 int i;
1166 // if this node is already visited, skip
1167 if ( Abc_NodeIsTravIdCurrent( pNode ) )
1168 return;
1169 // mark the node as visited
1170 Abc_NodeSetTravIdCurrent( pNode );
1171 // skip the PI
1172 if ( Abc_ObjIsCi(pNode) || Abc_AigNodeIsConst(pNode) )
1173 return;
1174 assert( Abc_ObjIsNode( pNode ) );
1175 // visit the transitive fanin of the node
1176 Abc_ObjForEachFanin( pNode, pFanin, i )
1177 Abc_AigDfs_rec( pFanin, vNodes );
1178 // visit the equivalent nodes
1179 if ( Abc_AigNodeIsChoice( pNode ) )
1180 for ( pFanin = (Abc_Obj_t *)pNode->pData; pFanin; pFanin = (Abc_Obj_t *)pFanin->pData )
1181 Abc_AigDfs_rec( pFanin, vNodes );
1182 // add the node after the fanins have been added
1183 Vec_PtrPush( vNodes, pNode );
1184}
1185
1198Vec_Ptr_t * Abc_AigDfs( Abc_Ntk_t * pNtk, int fCollectAll, int fCollectCos )
1199{
1200 Vec_Ptr_t * vNodes;
1201 Abc_Obj_t * pNode;
1202 int i;
1203 assert( Abc_NtkIsStrash(pNtk) );
1204 // set the traversal ID
1205 Abc_NtkIncrementTravId( pNtk );
1206 // start the array of nodes
1207 vNodes = Vec_PtrAlloc( 100 );
1208 // go through the PO nodes and call for each of them
1209 Abc_NtkForEachCo( pNtk, pNode, i )
1210 {
1211 Abc_AigDfs_rec( Abc_ObjFanin0(pNode), vNodes );
1212 Abc_NodeSetTravIdCurrent( pNode );
1213 if ( fCollectCos )
1214 Vec_PtrPush( vNodes, pNode );
1215 }
1216 // collect dangling nodes if asked to
1217 if ( fCollectAll )
1218 {
1219 Abc_NtkForEachNode( pNtk, pNode, i )
1220 if ( !Abc_NodeIsTravIdCurrent(pNode) )
1221 Abc_AigDfs_rec( pNode, vNodes );
1222 }
1223 return vNodes;
1224}
1225
1239{
1240 Vec_Ptr_t * vNodes;
1241 Abc_Obj_t * pNode;
1242 int i;
1243 assert( Abc_NtkIsStrash(pNtk) );
1244 // set the traversal ID
1245 Abc_NtkIncrementTravId( pNtk );
1246 // start the array of nodes
1247 vNodes = Vec_PtrAlloc( 100 );
1248 // collect cones of barbufs
1249 Abc_NtkForEachCo( pNtk, pNode, i )
1250 {
1251 if ( i < Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
1252 continue;
1253 Abc_AigDfs_rec( Abc_ObjFanin0(pNode), vNodes );
1254 Abc_NodeSetTravIdCurrent( pNode );
1255 // collect latch as a placeholder
1256 assert( Abc_ObjIsLatch(Abc_ObjFanout0(pNode)) );
1257 Vec_PtrPush( vNodes, Abc_ObjFanout0(pNode) );
1258 }
1259 // collect nodes of real POs
1260 Abc_NtkForEachCo( pNtk, pNode, i )
1261 {
1262 if ( i >= Abc_NtkCoNum(pNtk) - pNtk->nBarBufs )
1263 break;
1264 Abc_AigDfs_rec( Abc_ObjFanin0(pNode), vNodes );
1265 assert( Abc_ObjIsCo(pNode) );
1266 Abc_NodeSetTravIdCurrent( pNode );
1267 }
1268 return vNodes;
1269}
1270
1283{
1284 Abc_Obj_t * pFanout;
1285 int i;
1286 // if this node is already visited, skip
1287 if ( Abc_NodeIsTravIdCurrent( pNode ) )
1288 return;
1289 // mark the node as visited
1290 Abc_NodeSetTravIdCurrent( pNode );
1291 // skip the terminals
1292 if ( Abc_ObjIsCo(pNode) )
1293 return;
1294 assert( Abc_ObjIsNode(pNode) );
1295 // add the node to the structure
1296 Vec_VecPush( vLevels, pNode->Level, pNode );
1297 // visit the TFO
1298 Abc_ObjForEachFanout( pNode, pFanout, i )
1299 Abc_DfsLevelizedTfo_rec( pFanout, vLevels );
1300}
1301
1314{
1315 Vec_Vec_t * vLevels;
1316 Abc_Obj_t * pFanout;
1317 int i;
1318 assert( fTfi == 0 );
1319 assert( !Abc_NtkIsNetlist(pNode->pNtk) );
1320 // set the traversal ID
1321 Abc_NtkIncrementTravId( pNode->pNtk );
1322 vLevels = Vec_VecAlloc( 100 );
1323 if ( Abc_ObjIsNode(pNode) )
1324 Abc_DfsLevelizedTfo_rec( pNode, vLevels );
1325 else
1326 {
1327 assert( Abc_ObjIsCi(pNode) );
1328 Abc_NodeSetTravIdCurrent( pNode );
1329 Abc_ObjForEachFanout( pNode, pFanout, i )
1330 Abc_DfsLevelizedTfo_rec( pFanout, vLevels );
1331 }
1332 return vLevels;
1333}
1334
1335
1348{
1349 Abc_Obj_t * pNext;
1350 int i, Level;
1351 assert( !Abc_ObjIsNet(pNode) );
1352 // skip the PI
1353 if ( Abc_ObjIsCi(pNode) )
1354 return pNode->Level;
1355 assert( Abc_ObjIsNode( pNode ) || pNode->Type == ABC_OBJ_CONST1);
1356 // if this node is already visited, return
1357 if ( Abc_NodeIsTravIdCurrent( pNode ) )
1358 return pNode->Level;
1359 // mark the node as visited
1360 Abc_NodeSetTravIdCurrent( pNode );
1361 // visit the transitive fanin
1362 pNode->Level = 0;
1363 Abc_ObjForEachFanin( pNode, pNext, i )
1364 {
1365 Level = Abc_NtkLevel_rec( Abc_ObjFanin0Ntk(pNext) );
1366 if ( pNode->Level < (unsigned)Level )
1367 pNode->Level = Level;
1368 }
1369 if ( Abc_ObjFaninNum(pNode) > 0 && !Abc_ObjIsBarBuf(pNode) )
1370 pNode->Level++;
1371 return pNode->Level;
1372}
1373
1386{
1387 Abc_Obj_t * pNext;
1388 int i, Level;
1389 assert( !Abc_ObjIsNet(pNode) );
1390 // skip the PI
1391 if ( Abc_ObjIsCo(pNode) )
1392 return pNode->Level;
1393 assert( Abc_ObjIsNode( pNode ) || pNode->Type == ABC_OBJ_CONST1);
1394 // if this node is already visited, return
1395 if ( Abc_NodeIsTravIdCurrent( pNode ) )
1396 return pNode->Level;
1397 // mark the node as visited
1398 Abc_NodeSetTravIdCurrent( pNode );
1399 // visit the transitive fanin
1400 pNode->Level = 0;
1401 Abc_ObjForEachFanout( pNode, pNext, i )
1402 {
1403 Level = Abc_NtkLevelReverse_rec( Abc_ObjFanout0Ntk(pNext) );
1404 if ( pNode->Level < (unsigned)Level )
1405 pNode->Level = Level;
1406 }
1407 if ( Abc_ObjFaninNum(pNode) > 0 && !Abc_ObjIsBarBuf(pNode) )
1408 pNode->Level++;
1409 return pNode->Level;
1410}
1411
1424{
1425 Abc_Obj_t * pObj;
1426 Vec_Vec_t * vLevels;
1427 int nLevels, i;
1428 nLevels = Abc_NtkLevel( pNtk );
1429 vLevels = Vec_VecStart( nLevels + 1 );
1430 Abc_NtkForEachNode( pNtk, pObj, i )
1431 {
1432 assert( (int)pObj->Level <= nLevels );
1433 Vec_VecPush( vLevels, pObj->Level, pObj );
1434 }
1435 return vLevels;
1436}
1437
1450{
1451 Abc_Obj_t * pNode;
1452 int i, LevelsMax;
1453 // set the CI levels
1454 if ( pNtk->pManTime == NULL || pNtk->AndGateDelay <= 0 )
1455 Abc_NtkForEachCi( pNtk, pNode, i )
1456 pNode->Level = 0;
1457 else
1458 Abc_NtkForEachCi( pNtk, pNode, i )
1459 pNode->Level = (int)(Abc_MaxFloat(0, Abc_NodeReadArrivalWorst(pNode)) / pNtk->AndGateDelay);
1460 // perform the traversal
1461 LevelsMax = 0;
1462 Abc_NtkIncrementTravId( pNtk );
1463 if ( pNtk->nBarBufs == 0 )
1464 {
1465 Abc_NtkForEachNode( pNtk, pNode, i )
1466 {
1467 Abc_NtkLevel_rec( pNode );
1468 if ( LevelsMax < (int)pNode->Level )
1469 LevelsMax = (int)pNode->Level;
1470 }
1471 }
1472 else
1473 {
1474 Abc_NtkForEachLiPo( pNtk, pNode, i )
1475 {
1476 Abc_Obj_t * pDriver = Abc_ObjFanin0(pNode);
1477 Abc_NtkLevel_rec( pDriver );
1478 if ( LevelsMax < (int)pDriver->Level )
1479 LevelsMax = (int)pDriver->Level;
1480 // transfer the delay
1481 if ( i < pNtk->nBarBufs )
1482 Abc_ObjFanout0(Abc_ObjFanout0(pNode))->Level = pDriver->Level;
1483 }
1484 }
1485 return LevelsMax;
1486}
1487
1500{
1501 Abc_Obj_t * pNode;
1502 int i, LevelsMax;
1503 // set the CO levels to zero
1504 Abc_NtkForEachCo( pNtk, pNode, i )
1505 pNode->Level = 0;
1506 // perform the traversal
1507 LevelsMax = 0;
1508 Abc_NtkIncrementTravId( pNtk );
1509 Abc_NtkForEachNode( pNtk, pNode, i )
1510 {
1511 Abc_NtkLevelReverse_rec( pNode );
1512 if ( LevelsMax < (int)pNode->Level )
1513 LevelsMax = (int)pNode->Level;
1514 }
1515 return LevelsMax;
1516}
1518{
1519 int i, LevelMax = Abc_NtkLevelReverse( pNtk );
1520 Abc_Obj_t * pNode;
1521 Abc_NtkForEachObj( pNtk, pNode, i )
1522 pNode->Level = (int)(LevelMax - pNode->Level + 1);
1523 return LevelMax;
1524}
1525
1526
1539{
1540 Abc_Ntk_t * pNtk = pNode->pNtk;
1541 Abc_Obj_t * pFanin;
1542 int fAcyclic, i;
1543 assert( !Abc_ObjIsNet(pNode) );
1544 if ( Abc_ObjIsCi(pNode) || Abc_ObjIsBox(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
1545 return 1;
1546 assert( Abc_ObjIsNode(pNode) );
1547 // make sure the node is not visited
1548 assert( !Abc_NodeIsTravIdPrevious(pNode) );
1549 // check if the node is part of the combinational loop
1550 if ( Abc_NodeIsTravIdCurrent(pNode) )
1551 {
1552 fprintf( stdout, "Network \"%s\" contains combinational loop!\n", Abc_NtkName(pNtk) );
1553 fprintf( stdout, "Node \"%s\" is encountered twice on the following path to the COs:\n", Abc_ObjName(pNode) );
1554 return 0;
1555 }
1556 // mark this node as a node on the current path
1557 Abc_NodeSetTravIdCurrent( pNode );
1558 // visit the transitive fanin
1559 Abc_ObjForEachFanin( pNode, pFanin, i )
1560 {
1561 pFanin = Abc_ObjFanin0Ntk(pFanin);
1562 // make sure there is no mixing of networks
1563 assert( pFanin->pNtk == pNode->pNtk );
1564 // check if the fanin is visited
1565 if ( Abc_NodeIsTravIdPrevious(pFanin) )
1566 continue;
1567 // traverse the fanin's cone searching for the loop
1568 if ( (fAcyclic = Abc_NtkIsAcyclic_rec(pFanin)) )
1569 continue;
1570 // return as soon as the loop is detected
1571 fprintf( stdout, " %s ->", Abc_ObjName(pFanin) );
1572 return 0;
1573 }
1574 // visit choices
1575 if ( Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsChoice(pNode) )
1576 {
1577 for ( pFanin = (Abc_Obj_t *)pNode->pData; pFanin; pFanin = (Abc_Obj_t *)pFanin->pData )
1578 {
1579 // check if the fanin is visited
1580 if ( Abc_NodeIsTravIdPrevious(pFanin) )
1581 continue;
1582 // traverse the fanin's cone searching for the loop
1583 if ( (fAcyclic = Abc_NtkIsAcyclic_rec(pFanin)) )
1584 continue;
1585 // return as soon as the loop is detected
1586 fprintf( stdout, " %s", Abc_ObjName(pFanin) );
1587 fprintf( stdout, " (choice of %s) -> ", Abc_ObjName(pNode) );
1588 return 0;
1589 }
1590 }
1591 // mark this node as a visited node
1592 Abc_NodeSetTravIdPrevious( pNode );
1593 return 1;
1594}
1595
1615{
1616 Abc_Obj_t * pNode;
1617 int fAcyclic;
1618 int i;
1619 // set the traversal ID for this DFS ordering
1620 Abc_NtkIncrementTravId( pNtk );
1621 Abc_NtkIncrementTravId( pNtk );
1622 // pNode->TravId == pNet->nTravIds means "pNode is on the path"
1623 // pNode->TravId == pNet->nTravIds - 1 means "pNode is visited but is not on the path"
1624 // pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited"
1625 // traverse the network to detect cycles
1626 fAcyclic = 1;
1627 Abc_NtkForEachCo( pNtk, pNode, i )
1628 {
1629 pNode = Abc_ObjFanin0Ntk(Abc_ObjFanin0(pNode));
1630 if ( Abc_NodeIsTravIdPrevious(pNode) )
1631 continue;
1632 // traverse the output logic cone
1633 if ( (fAcyclic = Abc_NtkIsAcyclic_rec(pNode)) )
1634 continue;
1635 // stop as soon as the first loop is detected
1636 fprintf( stdout, " CO \"%s\"\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1637 break;
1638 }
1639 return fAcyclic;
1640}
1641
1654{
1655 Abc_Ntk_t * pNtk = pNode->pNtk;
1656 Abc_Obj_t * pFanin;
1657 int fAcyclic, i;
1658 assert( !Abc_ObjIsNet(pNode) );
1659 if ( Abc_ObjIsPi(pNode) || Abc_ObjIsLatch(pNode) || Abc_ObjIsBlackbox(pNode) )
1660 return 1;
1661 assert( Abc_ObjIsNode(pNode) || Abc_ObjIsBox(pNode) );
1662 // make sure the node is not visited
1663 assert( !Abc_NodeIsTravIdPrevious(pNode) );
1664 // check if the node is part of the combinational loop
1665 if ( Abc_NodeIsTravIdCurrent(pNode) )
1666 {
1667 fprintf( stdout, "Network \"%s\" contains combinational loop!\n", Abc_NtkName(pNtk) );
1668 if ( Abc_ObjIsBox(pNode) )
1669 fprintf( stdout, "Box \"%s\" is encountered twice on the following path to the COs:\n", Abc_ObjName(pNode) );
1670 else
1671 fprintf( stdout, "Node \"%s\" is encountered twice on the following path to the COs:\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1672 return 0;
1673 }
1674 // mark this node as a node on the current path
1675 Abc_NodeSetTravIdCurrent( pNode );
1676 // visit the transitive fanin
1677 Abc_ObjForEachFanin( pNode, pFanin, i )
1678 {
1679 if ( Abc_ObjIsBox(pNode) )
1680 pFanin = Abc_ObjFanin0(pFanin);
1681 pFanin = Abc_ObjFanin0Ntk(pFanin);
1682 if ( Abc_ObjIsBo(pFanin) )
1683 pFanin = Abc_ObjFanin0(pFanin);
1684 // check if the fanin is visited
1685 if ( Abc_ObjIsPi(pFanin) || Abc_ObjIsLatch(pFanin) || Abc_ObjIsBlackbox(pFanin) )
1686 continue;
1687 assert( Abc_ObjIsNode(pFanin) || Abc_ObjIsBox(pFanin) );
1688 if ( Abc_NodeIsTravIdPrevious(pFanin) )
1689 continue;
1690 // traverse the fanin's cone searching for the loop
1691 if ( (fAcyclic = Abc_NtkIsAcyclicWithBoxes_rec(pFanin)) )
1692 continue;
1693 // return as soon as the loop is detected
1694 fprintf( stdout, " %s ->", Abc_ObjName( Abc_ObjIsBox(pFanin) ? pFanin : Abc_ObjFanout0(pFanin) ) );
1695 return 0;
1696 }
1697 // mark this node as a visited node
1698 assert( Abc_ObjIsNode(pNode) || Abc_ObjIsBox(pNode) );
1699 Abc_NodeSetTravIdPrevious( pNode );
1700 return 1;
1701}
1703{
1704 Abc_Obj_t * pNode;
1705 int fAcyclic;
1706 int i;
1707 // set the traversal ID for this DFS ordering
1708 Abc_NtkIncrementTravId( pNtk );
1709 Abc_NtkIncrementTravId( pNtk );
1710 // pNode->TravId == pNet->nTravIds means "pNode is on the path"
1711 // pNode->TravId == pNet->nTravIds - 1 means "pNode is visited but is not on the path"
1712 // pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited"
1713 // traverse the network to detect cycles
1714 fAcyclic = 1;
1715 Abc_NtkForEachPo( pNtk, pNode, i )
1716 {
1717 pNode = Abc_ObjFanin0Ntk(Abc_ObjFanin0(pNode));
1718 if ( Abc_ObjIsBo(pNode) )
1719 pNode = Abc_ObjFanin0(pNode);
1720 if ( Abc_NodeIsTravIdPrevious(pNode) )
1721 continue;
1722 // traverse the output logic cone
1723 if ( (fAcyclic = Abc_NtkIsAcyclicWithBoxes_rec(pNode)) )
1724 continue;
1725 // stop as soon as the first loop is detected
1726 fprintf( stdout, " PO \"%s\"\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1727 break;
1728 }
1729 if ( fAcyclic )
1730 {
1731 Abc_NtkForEachLatchInput( pNtk, pNode, i )
1732 {
1733 pNode = Abc_ObjFanin0Ntk(Abc_ObjFanin0(pNode));
1734 if ( Abc_ObjIsBo(pNode) )
1735 pNode = Abc_ObjFanin0(pNode);
1736 if ( Abc_NodeIsTravIdPrevious(pNode) )
1737 continue;
1738 // traverse the output logic cone
1739 if ( (fAcyclic = Abc_NtkIsAcyclicWithBoxes_rec(pNode)) )
1740 continue;
1741 // stop as soon as the first loop is detected
1742 fprintf( stdout, " PO \"%s\"\n", Abc_ObjName(Abc_ObjFanout0(pNode)) );
1743 break;
1744 }
1745 }
1746 return fAcyclic;
1747}
1748
1749
1750
1762int Abc_NodeSetChoiceLevel_rec( Abc_Obj_t * pNode, int fMaximum )
1763{
1764 Abc_Obj_t * pTemp;
1765 int Level1, Level2, Level, LevelE;
1766 // skip the visited node
1767 if ( Abc_NodeIsTravIdCurrent( pNode ) )
1768 return (int)(ABC_PTRINT_T)pNode->pCopy;
1769 Abc_NodeSetTravIdCurrent( pNode );
1770 // compute levels of the children nodes
1771 Level1 = Abc_NodeSetChoiceLevel_rec( Abc_ObjFanin0(pNode), fMaximum );
1772 Level2 = Abc_NodeSetChoiceLevel_rec( Abc_ObjFanin1(pNode), fMaximum );
1773 Level = 1 + Abc_MaxInt( Level1, Level2 );
1774 if ( pNode->pData )
1775 {
1776 LevelE = Abc_NodeSetChoiceLevel_rec( (Abc_Obj_t *)pNode->pData, fMaximum );
1777 if ( fMaximum )
1778 Level = Abc_MaxInt( Level, LevelE );
1779 else
1780 Level = Abc_MinInt( Level, LevelE );
1781 // set the level of all equivalent nodes to be the same minimum
1782 for ( pTemp = (Abc_Obj_t *)pNode->pData; pTemp; pTemp = (Abc_Obj_t *)pTemp->pData )
1783 pTemp->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)Level;
1784 }
1785 pNode->pCopy = (Abc_Obj_t *)(ABC_PTRINT_T)Level;
1786 return Level;
1787}
1788
1804{
1805 Abc_Obj_t * pObj;
1806 int i, LevelMax, LevelCur;
1807 assert( Abc_NtkIsStrash(pNtk) );
1808 // set the new travid counter
1809 Abc_NtkIncrementTravId( pNtk );
1810 // set levels of the CI and constant
1811 Abc_NtkForEachCi( pNtk, pObj, i )
1812 {
1813 Abc_NodeSetTravIdCurrent( pObj );
1814 pObj->pCopy = NULL;
1815 }
1816 pObj = Abc_AigConst1( pNtk );
1817 Abc_NodeSetTravIdCurrent( pObj );
1818 pObj->pCopy = NULL;
1819 // set levels of all other nodes
1820 LevelMax = 0;
1821 Abc_NtkForEachCo( pNtk, pObj, i )
1822 {
1823 LevelCur = Abc_NodeSetChoiceLevel_rec( Abc_ObjFanin0(pObj), 1 );
1824 LevelMax = Abc_MaxInt( LevelMax, LevelCur );
1825 }
1826 return LevelMax;
1827}
1828
1842{
1843 Vec_Ptr_t * vNodes, * vLevels;
1844 Abc_Obj_t * pNode, ** ppHead;
1845 int LevelMax, i;
1846 assert( Abc_NtkIsStrash(pNtk) );
1847 // set the correct levels
1848 Abc_NtkCleanCopy( pNtk );
1849 LevelMax = Abc_AigSetChoiceLevels( pNtk );
1850 // relink nodes by level
1851 vLevels = Vec_PtrStart( LevelMax + 1 );
1852 Abc_NtkForEachNode( pNtk, pNode, i )
1853 {
1854 ppHead = ((Abc_Obj_t **)vLevels->pArray) + (int)(ABC_PTRINT_T)pNode->pCopy;
1855 pNode->pCopy = *ppHead;
1856 *ppHead = pNode;
1857 }
1858 // recollect nodes
1859 vNodes = Vec_PtrStart( Abc_NtkNodeNum(pNtk) );
1860 Vec_PtrForEachEntryStart( Abc_Obj_t *, vLevels, pNode, i, !fCollectCis )
1861 for ( ; pNode; pNode = pNode->pCopy )
1862 Vec_PtrPush( vNodes, pNode );
1863 Vec_PtrFree( vLevels );
1864 return vNodes;
1865}
1866
1879{
1880 if ( Abc_ObjIsCi(pObj) )
1881 return 0;
1882 if ( Abc_ObjFanoutNum(pObj) > 1 )
1883 return 0;
1884 return 1 + Abc_ObjSugraphSize(Abc_ObjFanin0(pObj)) +
1885 Abc_ObjSugraphSize(Abc_ObjFanin1(pObj));
1886}
1887
1900{
1901 Abc_Obj_t * pObj;
1902 int i;
1903 assert( Abc_NtkIsStrash(pNtk) );
1904 Abc_NtkForEachNode( pNtk, pObj, i )
1905 if ( Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsExorType(pObj) )
1906 printf( "%d(%d) ", 1 + Abc_ObjSugraphSize(Abc_ObjFanin0(pObj)) +
1907 Abc_ObjSugraphSize(Abc_ObjFanin1(pObj)), Abc_ObjFanoutNum(pObj) );
1908 printf( "\n" );
1909 return 1;
1910}
1911
1915
1916
1918
Vec_Ptr_t * Abc_NtkDfsWithBoxes(Abc_Ntk_t *pNtk)
Definition abcDfs.c:799
void Abc_AigDfs_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition abcDfs.c:1162
int Abc_NtkFunctionalIso(Abc_Ntk_t *pNtk, int iCo1, int iCo2, int fCommon)
Definition abcDfs.c:1048
int Abc_NtkPrintSubraphSizes(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1899
int Abc_NtkIsAcyclic(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1614
Vec_Vec_t * Abc_DfsLevelized(Abc_Obj_t *pNode, int fTfi)
Definition abcDfs.c:1313
int Abc_AigSetChoiceLevels(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1803
Vec_Ptr_t * Abc_NtkDfsNets(Abc_Ntk_t *pNtk)
Definition abcDfs.c:750
Vec_Ptr_t * Abc_NtkDfs2(Abc_Ntk_t *pNtk)
Definition abcDfs.c:127
void Abc_NtkNodeSupportInt_rec(Abc_Obj_t *pNode, Vec_Int_t *vNodes)
Definition abcDfs.c:918
Vec_Ptr_t * Abc_AigDfsMap(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1238
Vec_Ptr_t * Abc_AigDfs(Abc_Ntk_t *pNtk, int fCollectAll, int fCollectCos)
Definition abcDfs.c:1198
Gia_Man_t * Abc_NtkFunctionalIsoGia(Abc_Ntk_t *pNtk, int iCo1, int iCo2, int fCommon)
Definition abcDfs.c:983
ABC_NAMESPACE_IMPL_START void Abc_NtkDfs_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
DECLARATIONS ///.
Definition abcDfs.c:46
Vec_Vec_t * Abc_NtkLevelize(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1423
int Abc_ObjSugraphSize(Abc_Obj_t *pObj)
Definition abcDfs.c:1878
int Abc_NodeSetChoiceLevel_rec(Abc_Obj_t *pNode, int fMaximum)
Definition abcDfs.c:1762
int Abc_NtkLevelReverse(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1499
void Abc_NtkDfsReverse_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition abcDfs.c:187
int Abc_NtkIsAcyclicWithBoxes_rec(Abc_Obj_t *pNode)
Definition abcDfs.c:1653
void Abc_NtkSupportSum(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1136
int Abc_NtkFunctionalIsoGia_rec(Gia_Man_t *pNew, Abc_Obj_t *pNode)
Definition abcDfs.c:970
void Abc_DfsLevelizedTfo_rec(Abc_Obj_t *pNode, Vec_Vec_t *vLevels)
Definition abcDfs.c:1282
Vec_Ptr_t * Abc_NtkDfsReverseNodes(Abc_Ntk_t *pNtk, Abc_Obj_t **ppNodes, int nNodes)
Definition abcDfs.c:294
Vec_Ptr_t * Abc_NtkDfsReverse(Abc_Ntk_t *pNtk)
Definition abcDfs.c:221
int Abc_NtkSuppSizeTest(Abc_Ntk_t *p)
Definition abcDfs.c:1112
Vec_Ptr_t * Abc_NtkDfsHie(Abc_Ntk_t *pNtk, int fCollectAll)
Definition abcDfs.c:665
void Abc_NtkDfsReverseNodes_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition abcDfs.c:257
void Abc_NtkDfsNets_rec(Abc_Obj_t *pNet, Vec_Ptr_t *vNets)
Definition abcDfs.c:736
void Abc_NtkDfs_iter(Vec_Ptr_t *vStack, Abc_Obj_t *pRoot, Vec_Ptr_t *vNodes)
Definition abcDfs.c:515
int Abc_NtkIsAcyclic_rec(Abc_Obj_t *pNode)
Definition abcDfs.c:1538
void Abc_NtkDfsSeqReverse_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition abcDfs.c:458
Vec_Ptr_t * Abc_NtkDfsSeqReverse(Abc_Ntk_t *pNtk)
Definition abcDfs.c:485
Vec_Ptr_t * Abc_NtkDfsReverseNodesContained(Abc_Ntk_t *pNtk, Abc_Obj_t **ppNodes, int nNodes)
Definition abcDfs.c:329
int Abc_NtkLevelReverse_rec(Abc_Obj_t *pNode)
Definition abcDfs.c:1385
Vec_Ptr_t * Abc_NtkNodeSupport(Abc_Ntk_t *pNtk, Abc_Obj_t **ppNodes, int nNodes)
Definition abcDfs.c:890
int Abc_NtkIsAcyclicWithBoxes(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1702
int Abc_NtkLevel_rec(Abc_Obj_t *pNode)
Definition abcDfs.c:1347
Vec_Ptr_t * Abc_NtkDfs(Abc_Ntk_t *pNtk, int fCollectAll)
Definition abcDfs.c:82
void Abc_NtkDfsWithBoxes_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition abcDfs.c:777
int Abc_NtkFunctionalIsoInt(Abc_Ntk_t *pNtk, int iCo1, int iCo2, int fCommon)
Definition abcDfs.c:1033
Vec_Ptr_t * Abc_AigGetLevelizedOrder(Abc_Ntk_t *pNtk, int fCollectCis)
Definition abcDfs.c:1841
Vec_Ptr_t * Abc_NtkDfsIterNodes(Abc_Ntk_t *pNtk, Vec_Ptr_t *vRoots)
Definition abcDfs.c:611
int Abc_NtkIsDfsOrdered(Abc_Ntk_t *pNtk)
Definition abcDfs.c:698
int Abc_ObjSuppSize_rec(Abc_Obj_t *pObj)
Definition abcDfs.c:1071
Vec_Ptr_t * Abc_NtkDfsNodes(Abc_Ntk_t *pNtk, Abc_Obj_t **ppNodes, int nNodes)
Definition abcDfs.c:151
void Abc_NtkDfsSeq_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition abcDfs.c:401
Vec_Int_t * Abc_NtkNodeSupportInt(Abc_Ntk_t *pNtk, int iCo)
Definition abcDfs.c:940
int Abc_NtkLevel(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1449
int Abc_NtkLevelR(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1517
int Abc_ObjSuppSize(Abc_Obj_t *pObj)
Definition abcDfs.c:1096
void Abc_NtkNodeSupport_rec(Abc_Obj_t *pNode, Vec_Ptr_t *vNodes)
Definition abcDfs.c:826
Vec_Ptr_t * Abc_NtkDfsIter(Abc_Ntk_t *pNtk, int fCollectAll)
Definition abcDfs.c:573
Vec_Ptr_t * Abc_NtkSupport(Abc_Ntk_t *pNtk)
Definition abcDfs.c:859
Vec_Ptr_t * Abc_NtkDfsSeq(Abc_Ntk_t *pNtk)
Definition abcDfs.c:428
void Abc_NtkDfsHie_rec(Abc_Obj_t *pObj, Vec_Ptr_t *vNodes)
Definition abcDfs.c:638
#define Abc_NtkForEachBarBuf(pNtk, pNode, i)
Definition abc.h:482
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
#define Abc_NtkForEachCo(pNtk, pCo, i)
Definition abc.h:522
#define Abc_NtkForEachPo(pNtk, pPo, i)
Definition abc.h:520
#define Abc_NtkForEachObj(pNtk, pObj, i)
ITERATORS ///.
Definition abc.h:449
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition abc.h:527
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition abc.h:529
@ ABC_OBJ_CONST1
Definition abc.h:88
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition abcNames.c:49
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
ABC_DLL int Abc_NodeIsConst(Abc_Obj_t *pNode)
Definition abcObj.c:867
#define Abc_NtkForEachLatchInput(pNtk, pObj, i)
Definition abc.h:503
#define Abc_NtkForEachPi(pNtk, pPi, i)
Definition abc.h:516
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_AigLevel(Abc_Ntk_t *pNtk)
Definition abcAig.c:292
#define Abc_NtkForEachCi(pNtk, pCi, i)
Definition abc.h:518
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
Definition abcNtk.c:1421
ABC_DLL void Abc_NtkCleanCopy(Abc_Ntk_t *pNtk)
Definition abcUtil.c:540
ABC_DLL float Abc_NodeReadArrivalWorst(Abc_Obj_t *pNode)
Definition abcTiming.c:111
#define Abc_NtkForEachLiPo(pNtk, pCo, i)
Definition abc.h:524
ABC_DLL Abc_Obj_t * Abc_AigConst1(Abc_Ntk_t *pNtk)
Definition abcAig.c:683
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition abc.h:464
ABC_DLL int Abc_NodeIsExorType(Abc_Obj_t *pNode)
Definition abcUtil.c:1300
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
int Cec_ManVerifySimple(Gia_Man_t *p)
Definition cecCec.c:432
Cube * p
Definition exorList.c:222
void Gia_ManStop(Gia_Man_t *p)
Definition giaMan.c:82
void Gia_ManHashStart(Gia_Man_t *p)
Definition giaHash.c:125
Gia_Man_t * Gia_ManStart(int nObjsMax)
FUNCTION DEFINITIONS ///.
Definition giaMan.c:57
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
Gia_Man_t * Gia_ManCleanup(Gia_Man_t *p)
Definition giaScl.c:84
int Gia_ManHashAnd(Gia_Man_t *p, int iLit0, int iLit1)
Definition giaHash.c:576
char * pName
Definition abc.h:158
int nBarBufs
Definition abc.h:174
float AndGateDelay
Definition abc.h:194
Abc_ManTime_t * pManTime
Definition abc.h:192
char * pSpec
Definition abc.h:159
int nBarBufs2
Definition abc.h:175
void * pData
Definition abc.h:145
Abc_Ntk_t * pNtk
Definition abc.h:130
int iTemp
Definition abc.h:149
Abc_Obj_t * pCopy
Definition abc.h:148
unsigned Type
Definition abc.h:133
unsigned Level
Definition abc.h:142
char * pSpec
Definition gia.h:100
char * pName
Definition gia.h:99
#define assert(ex)
Definition util_old.h:213
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
#define Vec_PtrForEachEntryStart(Type, vVec, pEntry, i, Start)
Definition vecPtr.h:57
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition vecVec.h:42