ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
dsdTree.c
Go to the documentation of this file.
1
18
19#include "dsdInt.h"
20#include "misc/util/utilTruth.h"
21#include "opt/dau/dau.h"
22
24
25
29
30static void Dsd_TreeUnmark_rec( Dsd_Node_t * pNode );
31static void Dsd_TreeGetInfo_rec( Dsd_Node_t * pNode, int RankCur );
32static int Dsd_TreeCountNonTerminalNodes_rec( Dsd_Node_t * pNode );
33static int Dsd_TreeCountPrimeNodes_rec( Dsd_Node_t * pNode );
34static int Dsd_TreeCollectDecomposableVars_rec( DdManager * dd, Dsd_Node_t * pNode, int * pVars, int * nVars );
35static void Dsd_TreeCollectNodesDfs_rec( Dsd_Node_t * pNode, Dsd_Node_t * ppNodes[], int * pnNodes );
36static void Dsd_TreePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fCcmp, char * pInputNames[], char * pOutputName, int nOffset, int * pSigCounter, int fShortNames );
37static void Dsd_NodePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pOutputName, int nOffset, int * pSigCounter );
38
42
43static int s_DepthMax;
44static int s_GateSizeMax;
45
49
61Dsd_Node_t * Dsd_TreeNodeCreate( int Type, int nDecs, int BlockNum )
62{
63 // allocate memory for this node
64 Dsd_Node_t * p = (Dsd_Node_t *) ABC_ALLOC( char, sizeof(Dsd_Node_t) );
65 memset( p, 0, sizeof(Dsd_Node_t) );
66 p->Type = (Dsd_Type_t)Type; // the type of this block
67 p->nDecs = nDecs; // the number of decompositions
68 if ( p->nDecs )
69 {
70 p->pDecs = (Dsd_Node_t **) ABC_ALLOC( char, p->nDecs * sizeof(Dsd_Node_t *) );
71 p->pDecs[0] = NULL;
72 }
73 return p;
74}
75
87void Dsd_TreeNodeDelete( DdManager * dd, Dsd_Node_t * pNode )
88{
89 if ( pNode->G ) Cudd_RecursiveDeref( dd, pNode->G );
90 if ( pNode->S ) Cudd_RecursiveDeref( dd, pNode->S );
91 ABC_FREE( pNode->pDecs );
92 ABC_FREE( pNode );
93}
94
108{
109 int i;
110 for ( i = 0; i < pDsdMan->nRoots; i++ )
111 Dsd_TreeUnmark_rec( Dsd_Regular( pDsdMan->pRoots[i] ) );
112}
113
114
127void Dsd_TreeUnmark_rec( Dsd_Node_t * pNode )
128{
129 int i;
130
131 assert( pNode );
132 assert( !Dsd_IsComplement( pNode ) );
133 assert( pNode->nVisits > 0 );
134
135 if ( --pNode->nVisits ) // if this is not the last visit, return
136 return;
137
138 // upon the last visit, go through the list of successors and call recursively
139 if ( pNode->Type != DSD_NODE_BUF && pNode->Type != DSD_NODE_CONST1 )
140 for ( i = 0; i < pNode->nDecs; i++ )
141 Dsd_TreeUnmark_rec( Dsd_Regular(pNode->pDecs[i]) );
142}
143
156void Dsd_TreeNodeGetInfo( Dsd_Manager_t * pDsdMan, int * DepthMax, int * GateSizeMax )
157{
158 int i;
159 s_DepthMax = 0;
160 s_GateSizeMax = 0;
161
162 for ( i = 0; i < pDsdMan->nRoots; i++ )
163 Dsd_TreeGetInfo_rec( Dsd_Regular( pDsdMan->pRoots[i] ), 0 );
164
165 if ( DepthMax )
166 *DepthMax = s_DepthMax;
167 if ( GateSizeMax )
168 *GateSizeMax = s_GateSizeMax;
169}
170
183void Dsd_TreeNodeGetInfoOne( Dsd_Node_t * pNode, int * DepthMax, int * GateSizeMax )
184{
185 s_DepthMax = 0;
186 s_GateSizeMax = 0;
187
188 Dsd_TreeGetInfo_rec( Dsd_Regular(pNode), 0 );
189
190 if ( DepthMax )
191 *DepthMax = s_DepthMax;
192 if ( GateSizeMax )
193 *GateSizeMax = s_GateSizeMax;
194}
195
196
212void Dsd_TreeGetInfo_rec( Dsd_Node_t * pNode, int RankCur )
213{
214 int i;
215 int GateSize;
216
217 assert( pNode );
218 assert( !Dsd_IsComplement( pNode ) );
219 assert( pNode->nVisits >= 0 );
220
221 // we don't want the two-input gates to count for non-decomposable blocks
222 if ( pNode->Type == DSD_NODE_OR ||
223 pNode->Type == DSD_NODE_EXOR )
224 GateSize = 2;
225 else
226 GateSize = pNode->nDecs;
227
228 // update the max size of the node
229 if ( s_GateSizeMax < GateSize )
230 s_GateSizeMax = GateSize;
231
232 if ( pNode->nDecs < 2 )
233 return;
234
235 // update the max rank
236 if ( s_DepthMax < RankCur+1 )
237 s_DepthMax = RankCur+1;
238
239 // call recursively
240 for ( i = 0; i < pNode->nDecs; i++ )
241 Dsd_TreeGetInfo_rec( Dsd_Regular(pNode->pDecs[i]), RankCur+1 );
242}
243
256{
257 int i, Counter = 0;
258
259 assert( pNode );
260 assert( !Dsd_IsComplement( pNode ) );
261 assert( pNode->nVisits >= 0 );
262
263 if ( pNode->nDecs < 2 )
264 return 0;
265
266 // we don't want the two-input gates to count for non-decomposable blocks
267 if ( pNode->Type == DSD_NODE_OR )
268 Counter += pNode->nDecs - 1;
269 else if ( pNode->Type == DSD_NODE_EXOR )
270 Counter += 3*(pNode->nDecs - 1);
271 else if ( pNode->Type == DSD_NODE_PRIME && pNode->nDecs == 3 )
272 Counter += 3;
273
274 // call recursively
275 for ( i = 0; i < pNode->nDecs; i++ )
276 Counter += Dsd_TreeGetAigCost_rec( Dsd_Regular(pNode->pDecs[i]) );
277 return Counter;
278}
279
292{
293 return Dsd_TreeGetAigCost_rec( Dsd_Regular(pNode) );
294}
295
311{
312 int Counter, i;
313 Counter = 0;
314 for ( i = 0; i < pDsdMan->nRoots; i++ )
315 Counter += Dsd_TreeCountNonTerminalNodes_rec( Dsd_Regular( pDsdMan->pRoots[i] ) );
316 Dsd_TreeUnmark( pDsdMan );
317 return Counter;
318}
319
332{
333 int Counter = 0;
334
335 // go through the list of successors and call recursively
336 Counter = Dsd_TreeCountNonTerminalNodes_rec( Dsd_Regular(pRoot) );
337
338 Dsd_TreeUnmark_rec( Dsd_Regular(pRoot) );
339 return Counter;
340}
341
342
354int Dsd_TreeCountNonTerminalNodes_rec( Dsd_Node_t * pNode )
355{
356 int i;
357 int Counter = 0;
358
359 assert( pNode );
360 assert( !Dsd_IsComplement( pNode ) );
361 assert( pNode->nVisits >= 0 );
362
363 if ( pNode->nVisits++ ) // if this is not the first visit, return zero
364 return 0;
365
366 if ( pNode->nDecs <= 1 )
367 return 0;
368
369 // upon the first visit, go through the list of successors and call recursively
370 for ( i = 0; i < pNode->nDecs; i++ )
371 Counter += Dsd_TreeCountNonTerminalNodes_rec( Dsd_Regular(pNode->pDecs[i]) );
372
373 return Counter + 1;
374}
375
376
390{
391 int Counter, i;
392 Counter = 0;
393 for ( i = 0; i < pDsdMan->nRoots; i++ )
394 Counter += Dsd_TreeCountPrimeNodes_rec( Dsd_Regular( pDsdMan->pRoots[i] ) );
395 Dsd_TreeUnmark( pDsdMan );
396 return Counter;
397}
398
411{
412 int Counter = 0;
413
414 // go through the list of successors and call recursively
415 Counter = Dsd_TreeCountPrimeNodes_rec( Dsd_Regular(pRoot) );
416
417 Dsd_TreeUnmark_rec( Dsd_Regular(pRoot) );
418 return Counter;
419}
420
421
433int Dsd_TreeCountPrimeNodes_rec( Dsd_Node_t * pNode )
434{
435 int i;
436 int Counter = 0;
437
438 assert( pNode );
439 assert( !Dsd_IsComplement( pNode ) );
440 assert( pNode->nVisits >= 0 );
441
442 if ( pNode->nVisits++ ) // if this is not the first visit, return zero
443 return 0;
444
445 if ( pNode->nDecs <= 1 )
446 return 0;
447
448 // upon the first visit, go through the list of successors and call recursively
449 for ( i = 0; i < pNode->nDecs; i++ )
450 Counter += Dsd_TreeCountPrimeNodes_rec( Dsd_Regular(pNode->pDecs[i]) );
451
452 if ( pNode->Type == DSD_NODE_PRIME )
453 Counter++;
454
455 return Counter;
456}
457
458
471{
472 int nVars;
473
474 // set the vars collected to 0
475 nVars = 0;
476 Dsd_TreeCollectDecomposableVars_rec( pDsdMan->dd, Dsd_Regular(pDsdMan->pRoots[0]), pVars, &nVars );
477 // return the number of collected vars
478 return nVars;
479}
480
494int Dsd_TreeCollectDecomposableVars_rec( DdManager * dd, Dsd_Node_t * pNode, int * pVars, int * nVars )
495{
496 int fSkipThisNode, i;
497 Dsd_Node_t * pTemp;
498 int fVerbose = 0;
499
500 assert( pNode );
501 assert( !Dsd_IsComplement( pNode ) );
502
503 if ( pNode->nDecs <= 1 )
504 return 0;
505
506 // go through the list of successors and call recursively
507 fSkipThisNode = 0;
508 for ( i = 0; i < pNode->nDecs; i++ )
509 if ( Dsd_TreeCollectDecomposableVars_rec(dd, Dsd_Regular(pNode->pDecs[i]), pVars, nVars) )
510 fSkipThisNode = 1;
511
512 if ( !fSkipThisNode && (pNode->Type == DSD_NODE_OR || pNode->Type == DSD_NODE_EXOR || pNode->nDecs <= 4) )
513 {
514if ( fVerbose )
515printf( "Node of type <%d> (OR=6,EXOR=8,RAND=1): ", pNode->Type );
516
517 for ( i = 0; i < pNode->nDecs; i++ )
518 {
519 pTemp = Dsd_Regular(pNode->pDecs[i]);
520 if ( pTemp->Type == DSD_NODE_BUF )
521 {
522 if ( pVars )
523 pVars[ (*nVars)++ ] = pTemp->S->index;
524 else
525 (*nVars)++;
526
527if ( fVerbose )
528printf( "%d ", pTemp->S->index );
529 }
530 }
531if ( fVerbose )
532printf( "\n" );
533 }
534 else
535 fSkipThisNode = 1;
536
537
538 return fSkipThisNode;
539}
540
541
556{
557 Dsd_Node_t ** ppNodes;
558 int nNodes, nNodesAlloc;
559 int i;
560
561 nNodesAlloc = Dsd_TreeCountNonTerminalNodes(pDsdMan);
562 nNodes = 0;
563 ppNodes = ABC_ALLOC( Dsd_Node_t *, nNodesAlloc );
564 for ( i = 0; i < pDsdMan->nRoots; i++ )
565 Dsd_TreeCollectNodesDfs_rec( Dsd_Regular(pDsdMan->pRoots[i]), ppNodes, &nNodes );
566 Dsd_TreeUnmark( pDsdMan );
567 assert( nNodesAlloc == nNodes );
568 *pnNodes = nNodes;
569 return ppNodes;
570}
571
585Dsd_Node_t ** Dsd_TreeCollectNodesDfsOne( Dsd_Manager_t * pDsdMan, Dsd_Node_t * pNode, int * pnNodes )
586{
587 Dsd_Node_t ** ppNodes;
588 int nNodes, nNodesAlloc;
589 nNodesAlloc = Dsd_TreeCountNonTerminalNodesOne(pNode);
590 nNodes = 0;
591 ppNodes = ABC_ALLOC( Dsd_Node_t *, nNodesAlloc );
592 Dsd_TreeCollectNodesDfs_rec( Dsd_Regular(pNode), ppNodes, &nNodes );
593 Dsd_TreeUnmark_rec(Dsd_Regular(pNode));
594 assert( nNodesAlloc == nNodes );
595 *pnNodes = nNodes;
596 return ppNodes;
597}
598
599
611void Dsd_TreeCollectNodesDfs_rec( Dsd_Node_t * pNode, Dsd_Node_t * ppNodes[], int * pnNodes )
612{
613 int i;
614 assert( pNode );
615 assert( !Dsd_IsComplement(pNode) );
616 assert( pNode->nVisits >= 0 );
617
618 if ( pNode->nVisits++ ) // if this is not the first visit, return zero
619 return;
620 if ( pNode->nDecs <= 1 )
621 return;
622
623 // upon the first visit, go through the list of successors and call recursively
624 for ( i = 0; i < pNode->nDecs; i++ )
625 Dsd_TreeCollectNodesDfs_rec( Dsd_Regular(pNode->pDecs[i]), ppNodes, pnNodes );
626
627 ppNodes[ (*pnNodes)++ ] = pNode;
628}
629
642{
643 if ( pNode->Type == DSD_NODE_CONST1 )
644 return 0;
645 if ( pNode->Type == DSD_NODE_BUF )
646 return 0;
647 int MaxBlock = pNode->Type == DSD_NODE_PRIME ? pNode->nDecs : 0;
648 for ( int i = 0; i < pNode->nDecs; i++ )
649 {
650 int MaxThis = Dsd_TreeNonDsdMax_rec( Dsd_Regular( pNode->pDecs[i] ) );
651 MaxBlock = Abc_MaxInt( MaxBlock, MaxThis );
652 }
653 return MaxBlock;
654}
655int Dsd_TreeNonDsdMax( Dsd_Manager_t * pDsdMan, int Output )
656{
657 if ( Output == -1 )
658 {
659 int i, Res = 0;
660 for ( i = 0; i < pDsdMan->nRoots; i++ )
661 Res = Abc_MaxInt( Res, Dsd_TreeNonDsdMax_rec( Dsd_Regular( pDsdMan->pRoots[i] ) ) );
662 return Res;
663 }
664 else
665 {
666 assert( Output >= 0 && Output < pDsdMan->nRoots );
667 return Dsd_TreeNonDsdMax_rec( Dsd_Regular( pDsdMan->pRoots[Output] ) );
668 }
669}
670
683{
684 if ( pNode->Type == DSD_NODE_CONST1 )
685 return 0;
686 if ( pNode->Type == DSD_NODE_BUF )
687 return 1;
688 int nSuppSize = 0;
689 for ( int i = 0; i < pNode->nDecs; i++ )
690 nSuppSize += Dsd_TreeSuppSize_rec( Dsd_Regular( pNode->pDecs[i] ) );
691 return nSuppSize;
692}
693int Dsd_TreeSuppSize( Dsd_Manager_t * pDsdMan, int Output )
694{
695 if ( Output == -1 )
696 {
697 int i, Res = 0;
698 for ( i = 0; i < pDsdMan->nRoots; i++ )
699 Res += Dsd_TreeSuppSize_rec( Dsd_Regular( pDsdMan->pRoots[i] ) );
700 return Res;
701 }
702 else
703 {
704 assert( Output >= 0 && Output < pDsdMan->nRoots );
705 return Dsd_TreeSuppSize_rec( Dsd_Regular( pDsdMan->pRoots[Output] ) );
706 }
707}
708
721{
722 if ( pNode->Type == DSD_NODE_BUF ) {
723 Vec_StrPush( p, (int)(pNode->S->index >= 26 ? 'A' - 26 : 'a') + pNode->S->index );
724 return;
725 }
726 if ( pNode->Type == DSD_NODE_PRIME )
727 Vec_StrPush( p, '{' );
728 else if ( pNode->Type == DSD_NODE_OR )
729 Vec_StrPush( p, '(' );
730 else if ( pNode->Type == DSD_NODE_EXOR )
731 Vec_StrPush( p, '[' );
732 else assert( 0 );
733 for ( int i = 0; i < pNode->nDecs; i++ )
734 {
735 Dsd_Node_t * pInput = Dsd_Regular( pNode->pDecs[i] );
736 if ( pInput != pNode->pDecs[i] )
737 Vec_StrPush( p, '~' );
738 Dsd_TreePrint3_rec( p, pInput );
739 }
740 if ( pNode->Type == DSD_NODE_PRIME )
741 Vec_StrPush( p, '}' );
742 else if ( pNode->Type == DSD_NODE_OR )
743 Vec_StrPush( p, ')' );
744 else if ( pNode->Type == DSD_NODE_EXOR )
745 Vec_StrPush( p, ']' );
746 else assert( 0 );
747}
748void Dsd_TreePrint3( void * pStr, Dsd_Manager_t * pDsdMan, int Output )
749{
750 Vec_Str_t * p = (Vec_Str_t *)pStr;
751 assert( Output >= 0 && Output < pDsdMan->nRoots );
752 Dsd_Node_t * pNode = Dsd_Regular( pDsdMan->pRoots[Output] );
753 int fCompl = pNode != pDsdMan->pRoots[Output];
754 if ( pNode->Type == DSD_NODE_CONST1 )
755 Vec_StrPush( p, fCompl ? '0' : '1' );
756 else {
757 if ( fCompl )
758 Vec_StrPush( p, '~' );
759 Dsd_TreePrint3_rec( p, pNode );
760 }
761 Vec_StrPush( p, '\0' );
762}
763
776{
777 if ( pNode->Type == DSD_NODE_BUF ) {
778 Vec_StrPush( p, (int)(pNode->S->index >= 26 ? 'A' - 26 : 'a') + pNode->S->index );
779 return;
780 }
781 if ( pNode->Type == DSD_NODE_PRIME )
782 Vec_StrPush( p, '{' );
783 else if ( pNode->Type == DSD_NODE_OR )
784 Vec_StrPush( p, '(' );
785 else if ( pNode->Type == DSD_NODE_EXOR )
786 Vec_StrPush( p, '[' );
787 else assert( 0 );
788 for ( int i = 0; i < pNode->nDecs; i++ )
789 {
790 Dsd_Node_t * pInput = Dsd_Regular( pNode->pDecs[i] );
791 if ( (pInput != pNode->pDecs[i]) ^ (pNode->Type == DSD_NODE_OR) ^ (pInput->Type == DSD_NODE_OR) )
792 Vec_StrPush( p, '~' );
793 Dsd_TreePrint4_rec( p, pInput );
794 }
795 if ( pNode->Type == DSD_NODE_PRIME )
796 Vec_StrPush( p, '}' );
797 else if ( pNode->Type == DSD_NODE_OR )
798 Vec_StrPush( p, ')' );
799 else if ( pNode->Type == DSD_NODE_EXOR )
800 Vec_StrPush( p, ']' );
801 else assert( 0 );
802}
803void Dsd_TreePrint4( void * pStr, Dsd_Manager_t * pDsdMan, int Output )
804{
805 Vec_Str_t * p = (Vec_Str_t *)pStr;
806 assert( Output >= 0 && Output < pDsdMan->nRoots );
807 Dsd_Node_t * pNode = Dsd_Regular( pDsdMan->pRoots[Output] );
808 int fCompl = pNode != pDsdMan->pRoots[Output];
809 if ( pNode->Type == DSD_NODE_CONST1 )
810 Vec_StrPush( p, fCompl ? '0' : '1' );
811 else {
812 if ( fCompl ^ (pNode->Type == DSD_NODE_OR) )
813 Vec_StrPush( p, '~' );
814 Dsd_TreePrint4_rec( p, pNode );
815 }
816 Vec_StrPush( p, '\0' );
817}
818
830void Dsd_TreePrint( FILE * pFile, Dsd_Manager_t * pDsdMan, char * pInputNames[], char * pOutputNames[], int fShortNames, int Output, int OffSet )
831{
832 Dsd_Node_t * pNode;
833 int SigCounter;
834 int i;
835 SigCounter = 1;
836
837 if ( Output == -1 )
838 {
839 for ( i = 0; i < pDsdMan->nRoots; i++ )
840 {
841 pNode = Dsd_Regular( pDsdMan->pRoots[i] );
842 Dsd_TreePrint_rec( pFile, pNode, (pNode != pDsdMan->pRoots[i]), pInputNames, pOutputNames[i], OffSet, &SigCounter, fShortNames );
843 }
844 }
845 else
846 {
847 assert( Output >= 0 && Output < pDsdMan->nRoots );
848 pNode = Dsd_Regular( pDsdMan->pRoots[Output] );
849 Dsd_TreePrint_rec( pFile, pNode, (pNode != pDsdMan->pRoots[Output]), pInputNames, pOutputNames[Output], OffSet, &SigCounter, fShortNames );
850 }
851}
852
864void Dsd_TreePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pInputNames[], char * pOutputName, int nOffset, int * pSigCounter, int fShortNames )
865{
866 char Buffer[100];
867 Dsd_Node_t * pInput;
868 int * pInputNums;
869 int fCompNew, i;
870
871 assert( pNode->Type == DSD_NODE_BUF || pNode->Type == DSD_NODE_CONST1 ||
872 pNode->Type == DSD_NODE_PRIME || pNode->Type == DSD_NODE_OR || pNode->Type == DSD_NODE_EXOR );
873
874 Extra_PrintSymbols( pFile, ' ', nOffset, 0 );
875 if ( !fComp )
876 fprintf( pFile, "%s = ", pOutputName );
877 else
878 fprintf( pFile, "~%s = ", pOutputName );
879 pInputNums = ABC_ALLOC( int, pNode->nDecs );
880 if ( pNode->Type == DSD_NODE_CONST1 )
881 {
882 fprintf( pFile, " Constant 1.\n" );
883 }
884 else if ( pNode->Type == DSD_NODE_BUF )
885 {
886 if ( fShortNames )
887 fprintf( pFile, "%d", 'a' + pNode->S->index );
888 else
889 fprintf( pFile, "%s", pInputNames[pNode->S->index] );
890 fprintf( pFile, "\n" );
891 }
892 else if ( pNode->Type == DSD_NODE_PRIME )
893 {
894 // print the line
895 fprintf( pFile, "PRIME(" );
896 for ( i = 0; i < pNode->nDecs; i++ )
897 {
898 pInput = Dsd_Regular( pNode->pDecs[i] );
899 fCompNew = (int)( pInput != pNode->pDecs[i] );
900 if ( i )
901 fprintf( pFile, "," );
902 if ( fCompNew )
903 fprintf( pFile, " ~" );
904 else
905 fprintf( pFile, " " );
906 if ( pInput->Type == DSD_NODE_BUF )
907 {
908 pInputNums[i] = 0;
909 if ( fShortNames )
910 fprintf( pFile, "%d", pInput->S->index );
911 else
912 fprintf( pFile, "%s", pInputNames[pInput->S->index] );
913 }
914 else
915 {
916 pInputNums[i] = (*pSigCounter)++;
917 fprintf( pFile, "<%d>", pInputNums[i] );
918 }
919 //if ( fCompNew )
920 // fprintf( pFile, "" );
921 }
922 fprintf( pFile, " )\n" );
923 // call recursively for the following blocks
924 for ( i = 0; i < pNode->nDecs; i++ )
925 if ( pInputNums[i] )
926 {
927 pInput = Dsd_Regular( pNode->pDecs[i] );
928 sprintf( Buffer, "<%d>", pInputNums[i] );
929 Dsd_TreePrint_rec( pFile, Dsd_Regular( pNode->pDecs[i] ), 0, pInputNames, Buffer, nOffset + 6, pSigCounter, fShortNames );
930 }
931 }
932 else if ( pNode->Type == DSD_NODE_OR )
933 {
934 // print the line
935 fprintf( pFile, "OR(" );
936 for ( i = 0; i < pNode->nDecs; i++ )
937 {
938 pInput = Dsd_Regular( pNode->pDecs[i] );
939 fCompNew = (int)( pInput != pNode->pDecs[i] );
940 if ( i )
941 fprintf( pFile, "," );
942 if ( fCompNew )
943 fprintf( pFile, " ~" );
944 else
945 fprintf( pFile, " " );
946 if ( pInput->Type == DSD_NODE_BUF )
947 {
948 pInputNums[i] = 0;
949 if ( fShortNames )
950 fprintf( pFile, "%c", 'a' + pInput->S->index );
951 else
952 fprintf( pFile, "%s", pInputNames[pInput->S->index] );
953 }
954 else
955 {
956 pInputNums[i] = (*pSigCounter)++;
957 fprintf( pFile, "<%d>", pInputNums[i] );
958 }
959 //if ( fCompNew )
960 // fprintf( pFile, "" );
961 }
962 fprintf( pFile, " )\n" );
963 // call recursively for the following blocks
964 for ( i = 0; i < pNode->nDecs; i++ )
965 if ( pInputNums[i] )
966 {
967 pInput = Dsd_Regular( pNode->pDecs[i] );
968 sprintf( Buffer, "<%d>", pInputNums[i] );
969 Dsd_TreePrint_rec( pFile, Dsd_Regular( pNode->pDecs[i] ), 0, pInputNames, Buffer, nOffset + 6, pSigCounter, fShortNames );
970 }
971 }
972 else if ( pNode->Type == DSD_NODE_EXOR )
973 {
974 // print the line
975 fprintf( pFile, "EXOR(" );
976 for ( i = 0; i < pNode->nDecs; i++ )
977 {
978 pInput = Dsd_Regular( pNode->pDecs[i] );
979 fCompNew = (int)( pInput != pNode->pDecs[i] );
980 if ( i )
981 fprintf( pFile, "," );
982 if ( fCompNew )
983 fprintf( pFile, " ~" );
984 else
985 fprintf( pFile, " " );
986 if ( pInput->Type == DSD_NODE_BUF )
987 {
988 pInputNums[i] = 0;
989 if ( fShortNames )
990 fprintf( pFile, "%c", 'a' + pInput->S->index );
991 else
992 fprintf( pFile, "%s", pInputNames[pInput->S->index] );
993 }
994 else
995 {
996 pInputNums[i] = (*pSigCounter)++;
997 fprintf( pFile, "<%d>", pInputNums[i] );
998 }
999 //if ( fCompNew )
1000 // fprintf( pFile, "" );
1001 }
1002 fprintf( pFile, " )\n" );
1003 // call recursively for the following blocks
1004 for ( i = 0; i < pNode->nDecs; i++ )
1005 if ( pInputNums[i] )
1006 {
1007 pInput = Dsd_Regular( pNode->pDecs[i] );
1008 sprintf( Buffer, "<%d>", pInputNums[i] );
1009 Dsd_TreePrint_rec( pFile, Dsd_Regular( pNode->pDecs[i] ), 0, pInputNames, Buffer, nOffset + 6, pSigCounter, fShortNames );
1010 }
1011 }
1012 ABC_FREE( pInputNums );
1013}
1014
1026word Dsd_TreeFunc2Truth_rec( DdManager * dd, DdNode * bFunc )
1027{
1028 word Cof0, Cof1;
1029 int Level;
1030 if ( bFunc == b0 )
1031 return 0;
1032 if ( bFunc == b1 )
1033 return ~(word)0;
1034 if ( Cudd_IsComplement(bFunc) )
1035 return ~Dsd_TreeFunc2Truth_rec( dd, Cudd_Not(bFunc) );
1036 Level = dd->perm[bFunc->index];
1037 assert( Level >= 0 && Level < 6 );
1038 Cof0 = Dsd_TreeFunc2Truth_rec( dd, cuddE(bFunc) );
1039 Cof1 = Dsd_TreeFunc2Truth_rec( dd, cuddT(bFunc) );
1040 return (s_Truths6[Level] & Cof1) | (~s_Truths6[Level] & Cof0);
1041}
1042void Dsd_TreePrint2_rec( FILE * pFile, DdManager * dd, Dsd_Node_t * pNode, int fComp, char * pInputNames[] )
1043{
1044 int i;
1045 if ( pNode->Type == DSD_NODE_CONST1 )
1046 {
1047 fprintf( pFile, "Const%d", !fComp );
1048 return;
1049 }
1050 assert( pNode->Type == DSD_NODE_BUF || pNode->Type == DSD_NODE_PRIME || pNode->Type == DSD_NODE_OR || pNode->Type == DSD_NODE_EXOR );
1051// fprintf( pFile, "%s", (fComp ^ (pNode->Type == DSD_NODE_OR))? "!" : "" );
1052 if ( pNode->Type == DSD_NODE_BUF )
1053 {
1054 fprintf( pFile, "%s", fComp? "!" : "" );
1055 fprintf( pFile, "%s", pInputNames[pNode->S->index] );
1056 }
1057 else if ( pNode->Type == DSD_NODE_PRIME )
1058 {
1059 fprintf( pFile, " " );
1060 if ( pNode->nDecs <= 6 )
1061 {
1062 char pCanonPerm[6]; int uCanonPhase;
1063 // compute truth table
1064 DdNode * bFunc = Dsd_TreeGetPrimeFunction( dd, pNode );
1065 word uTruth = Dsd_TreeFunc2Truth_rec( dd, bFunc );
1066 Cudd_Ref( bFunc );
1067 Cudd_RecursiveDeref( dd, bFunc );
1068 // canonicize truth table
1069 uCanonPhase = Abc_TtCanonicize( &uTruth, pNode->nDecs, pCanonPerm );
1070 fprintf( pFile, "%s", (fComp ^ ((uCanonPhase >> pNode->nDecs) & 1)) ? "!" : "" );
1071 Abc_TtPrintHexRev( pFile, &uTruth, pNode->nDecs );
1072 fprintf( pFile, "{" );
1073 for ( i = 0; i < pNode->nDecs; i++ )
1074 {
1075 Dsd_Node_t * pInput = pNode->pDecs[(int)pCanonPerm[i]];
1076 Dsd_TreePrint2_rec( pFile, dd, Dsd_Regular(pInput), Dsd_IsComplement(pInput) ^ ((uCanonPhase>>i)&1), pInputNames );
1077 }
1078 fprintf( pFile, "} " );
1079 }
1080 else
1081 {
1082 fprintf( pFile, "|%d|", pNode->nDecs );
1083 fprintf( pFile, "{" );
1084 for ( i = 0; i < pNode->nDecs; i++ )
1085 Dsd_TreePrint2_rec( pFile, dd, Dsd_Regular(pNode->pDecs[i]), Dsd_IsComplement(pNode->pDecs[i]), pInputNames );
1086 fprintf( pFile, "} " );
1087 }
1088 }
1089 else if ( pNode->Type == DSD_NODE_OR )
1090 {
1091 fprintf( pFile, "%s", !fComp? "!" : "" );
1092 fprintf( pFile, "(" );
1093 for ( i = 0; i < pNode->nDecs; i++ )
1094 Dsd_TreePrint2_rec( pFile, dd, Dsd_Regular(pNode->pDecs[i]), !Dsd_IsComplement(pNode->pDecs[i]), pInputNames );
1095 fprintf( pFile, ")" );
1096 }
1097 else if ( pNode->Type == DSD_NODE_EXOR )
1098 {
1099 fprintf( pFile, "%s", fComp? "!" : "" );
1100 fprintf( pFile, "[" );
1101 for ( i = 0; i < pNode->nDecs; i++ )
1102 Dsd_TreePrint2_rec( pFile, dd, Dsd_Regular(pNode->pDecs[i]), Dsd_IsComplement(pNode->pDecs[i]), pInputNames );
1103 fprintf( pFile, "]" );
1104 }
1105}
1106void Dsd_TreePrint2( FILE * pFile, Dsd_Manager_t * pDsdMan, char * pInputNames[], char * pOutputNames[], int Output )
1107{
1108 if ( Output == -1 )
1109 {
1110 int i;
1111 for ( i = 0; i < pDsdMan->nRoots; i++ )
1112 {
1113 fprintf( pFile, "%8s = ", pOutputNames[i] );
1114 Dsd_TreePrint2_rec( pFile, pDsdMan->dd, Dsd_Regular(pDsdMan->pRoots[i]), Dsd_IsComplement(pDsdMan->pRoots[i]), pInputNames );
1115 fprintf( pFile, "\n" );
1116 }
1117 }
1118 else
1119 {
1120 assert( Output >= 0 && Output < pDsdMan->nRoots );
1121 fprintf( pFile, "%8s = ", pOutputNames[Output] );
1122 Dsd_TreePrint2_rec( pFile, pDsdMan->dd, Dsd_Regular(pDsdMan->pRoots[Output]), Dsd_IsComplement(pDsdMan->pRoots[Output]), pInputNames );
1123 fprintf( pFile, "\n" );
1124 }
1125}
1126
1138void Dsd_NodePrint( FILE * pFile, Dsd_Node_t * pNode )
1139{
1140 Dsd_Node_t * pNodeR;
1141 int SigCounter = 1;
1142 pNodeR = Dsd_Regular(pNode);
1143 Dsd_NodePrint_rec( pFile, pNodeR, pNodeR != pNode, "F", 0, &SigCounter );
1144}
1145
1157void Dsd_NodePrint_rec( FILE * pFile, Dsd_Node_t * pNode, int fComp, char * pOutputName, int nOffset, int * pSigCounter )
1158{
1159 char Buffer[100];
1160 Dsd_Node_t * pInput;
1161 int * pInputNums;
1162 int fCompNew, i;
1163
1164 assert( pNode->Type == DSD_NODE_BUF || pNode->Type == DSD_NODE_CONST1 ||
1165 pNode->Type == DSD_NODE_PRIME || pNode->Type == DSD_NODE_OR || pNode->Type == DSD_NODE_EXOR );
1166
1167 Extra_PrintSymbols( pFile, ' ', nOffset, 0 );
1168 if ( !fComp )
1169 fprintf( pFile, "%s = ", pOutputName );
1170 else
1171 fprintf( pFile, "~%s = ", pOutputName );
1172 pInputNums = ABC_ALLOC( int, pNode->nDecs );
1173 if ( pNode->Type == DSD_NODE_CONST1 )
1174 {
1175 fprintf( pFile, " Constant 1.\n" );
1176 }
1177 else if ( pNode->Type == DSD_NODE_BUF )
1178 {
1179 fprintf( pFile, " " );
1180 fprintf( pFile, "%c", 'a' + pNode->S->index );
1181 fprintf( pFile, "\n" );
1182 }
1183 else if ( pNode->Type == DSD_NODE_PRIME )
1184 {
1185 // print the line
1186 fprintf( pFile, "PRIME(" );
1187 for ( i = 0; i < pNode->nDecs; i++ )
1188 {
1189 pInput = Dsd_Regular( pNode->pDecs[i] );
1190 fCompNew = (int)( pInput != pNode->pDecs[i] );
1191 assert( fCompNew == 0 );
1192 if ( i )
1193 fprintf( pFile, "," );
1194 if ( pInput->Type == DSD_NODE_BUF )
1195 {
1196 pInputNums[i] = 0;
1197 fprintf( pFile, " %c", 'a' + pInput->S->index );
1198 }
1199 else
1200 {
1201 pInputNums[i] = (*pSigCounter)++;
1202 fprintf( pFile, " <%d>", pInputNums[i] );
1203 }
1204 if ( fCompNew )
1205 fprintf( pFile, "\'" );
1206 }
1207 fprintf( pFile, " )\n" );
1208/*
1209 fprintf( pFile, " ) " );
1210 {
1211 DdNode * bLocal;
1212 bLocal = Dsd_TreeGetPrimeFunction( dd, pNodeDsd ); Cudd_Ref( bLocal );
1213 Extra_bddPrint( dd, bLocal );
1214 Cudd_RecursiveDeref( dd, bLocal );
1215 }
1216*/
1217 // call recursively for the following blocks
1218 for ( i = 0; i < pNode->nDecs; i++ )
1219 if ( pInputNums[i] )
1220 {
1221 pInput = Dsd_Regular( pNode->pDecs[i] );
1222 sprintf( Buffer, "<%d>", pInputNums[i] );
1223 Dsd_NodePrint_rec( pFile, Dsd_Regular( pNode->pDecs[i] ), 0, Buffer, nOffset + 6, pSigCounter );
1224 }
1225 }
1226 else if ( pNode->Type == DSD_NODE_OR )
1227 {
1228 // print the line
1229 fprintf( pFile, "OR(" );
1230 for ( i = 0; i < pNode->nDecs; i++ )
1231 {
1232 pInput = Dsd_Regular( pNode->pDecs[i] );
1233 fCompNew = (int)( pInput != pNode->pDecs[i] );
1234 if ( i )
1235 fprintf( pFile, "," );
1236 if ( pInput->Type == DSD_NODE_BUF )
1237 {
1238 pInputNums[i] = 0;
1239 fprintf( pFile, " %c", 'a' + pInput->S->index );
1240 }
1241 else
1242 {
1243 pInputNums[i] = (*pSigCounter)++;
1244 fprintf( pFile, " <%d>", pInputNums[i] );
1245 }
1246 if ( fCompNew )
1247 fprintf( pFile, "\'" );
1248 }
1249 fprintf( pFile, " )\n" );
1250 // call recursively for the following blocks
1251 for ( i = 0; i < pNode->nDecs; i++ )
1252 if ( pInputNums[i] )
1253 {
1254 pInput = Dsd_Regular( pNode->pDecs[i] );
1255 sprintf( Buffer, "<%d>", pInputNums[i] );
1256 Dsd_NodePrint_rec( pFile, Dsd_Regular( pNode->pDecs[i] ), 0, Buffer, nOffset + 6, pSigCounter );
1257 }
1258 }
1259 else if ( pNode->Type == DSD_NODE_EXOR )
1260 {
1261 // print the line
1262 fprintf( pFile, "EXOR(" );
1263 for ( i = 0; i < pNode->nDecs; i++ )
1264 {
1265 pInput = Dsd_Regular( pNode->pDecs[i] );
1266 fCompNew = (int)( pInput != pNode->pDecs[i] );
1267 assert( fCompNew == 0 );
1268 if ( i )
1269 fprintf( pFile, "," );
1270 if ( pInput->Type == DSD_NODE_BUF )
1271 {
1272 pInputNums[i] = 0;
1273 fprintf( pFile, " %c", 'a' + pInput->S->index );
1274 }
1275 else
1276 {
1277 pInputNums[i] = (*pSigCounter)++;
1278 fprintf( pFile, " <%d>", pInputNums[i] );
1279 }
1280 if ( fCompNew )
1281 fprintf( pFile, "\'" );
1282 }
1283 fprintf( pFile, " )\n" );
1284 // call recursively for the following blocks
1285 for ( i = 0; i < pNode->nDecs; i++ )
1286 if ( pInputNums[i] )
1287 {
1288 pInput = Dsd_Regular( pNode->pDecs[i] );
1289 sprintf( Buffer, "<%d>", pInputNums[i] );
1290 Dsd_NodePrint_rec( pFile, Dsd_Regular( pNode->pDecs[i] ), 0, Buffer, nOffset + 6, pSigCounter );
1291 }
1292 }
1293 ABC_FREE( pInputNums );
1294}
1295
1296
1309DdNode * Dsd_TreeGetPrimeFunctionOld( DdManager * dd, Dsd_Node_t * pNode, int fRemap )
1310{
1311 DdNode * bCof0, * bCof1, * bCube0, * bCube1, * bNewFunc, * bTemp;
1312 int i;
1313 static int Permute[MAXINPUTS];
1314
1315 assert( pNode );
1316 assert( !Dsd_IsComplement( pNode ) );
1317 assert( pNode->Type == DSD_NODE_PRIME );
1318
1319 // transform the function of this block to depend on inputs
1320 // corresponding to the formal inputs
1321
1322 // first, substitute those inputs that have some blocks associated with them
1323 // second, remap the inputs to the top of the manager (then, it is easy to output them)
1324
1325 // start the function
1326 bNewFunc = pNode->G; Cudd_Ref( bNewFunc );
1327 // go over all primary inputs
1328 for ( i = 0; i < pNode->nDecs; i++ )
1329 if ( pNode->pDecs[i]->Type != DSD_NODE_BUF ) // remap only if it is not the buffer
1330 {
1331 bCube0 = Extra_bddFindOneCube( dd, Cudd_Not(pNode->pDecs[i]->G) ); Cudd_Ref( bCube0 );
1332 bCof0 = Cudd_Cofactor( dd, bNewFunc, bCube0 ); Cudd_Ref( bCof0 );
1333 Cudd_RecursiveDeref( dd, bCube0 );
1334
1335 bCube1 = Extra_bddFindOneCube( dd, pNode->pDecs[i]->G ); Cudd_Ref( bCube1 );
1336 bCof1 = Cudd_Cofactor( dd, bNewFunc, bCube1 ); Cudd_Ref( bCof1 );
1337 Cudd_RecursiveDeref( dd, bCube1 );
1338
1339 Cudd_RecursiveDeref( dd, bNewFunc );
1340
1341 // use the variable in the i-th level of the manager
1342// bNewFunc = Cudd_bddIte( dd, dd->vars[dd->invperm[i]],bCof1,bCof0 ); Cudd_Ref( bNewFunc );
1343 // use the first variale in the support of the component
1344 bNewFunc = Cudd_bddIte( dd, dd->vars[pNode->pDecs[i]->S->index],bCof1,bCof0 ); Cudd_Ref( bNewFunc );
1345 Cudd_RecursiveDeref( dd, bCof0 );
1346 Cudd_RecursiveDeref( dd, bCof1 );
1347 }
1348
1349 if ( fRemap )
1350 {
1351 // remap the function to the top of the manager
1352 // remap the function to the first variables of the manager
1353 for ( i = 0; i < pNode->nDecs; i++ )
1354 // Permute[ pNode->pDecs[i]->S->index ] = dd->invperm[i];
1355 Permute[ pNode->pDecs[i]->S->index ] = i;
1356
1357 bNewFunc = Cudd_bddPermute( dd, bTemp = bNewFunc, Permute ); Cudd_Ref( bNewFunc );
1358 Cudd_RecursiveDeref( dd, bTemp );
1359 }
1360
1361 Cudd_Deref( bNewFunc );
1362 return bNewFunc;
1363}
1364
1365
1370
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
#define b0
Definition bbrImage.c:96
#define b1
Definition bbrImage.c:97
#define MAXINPUTS
INCLUDES ///.
Definition cas.h:38
unsigned Abc_TtCanonicize(word *pTruth, int nVars, char *pCanonPerm)
FUNCTION DECLARATIONS ///.
Definition dauCanon.c:1036
int Dsd_TreeCountPrimeNodesOne(Dsd_Node_t *pRoot)
Definition dsdTree.c:410
void Dsd_TreePrint3_rec(Vec_Str_t *p, Dsd_Node_t *pNode)
Definition dsdTree.c:720
Dsd_Node_t ** Dsd_TreeCollectNodesDfsOne(Dsd_Manager_t *pDsdMan, Dsd_Node_t *pNode, int *pnNodes)
Definition dsdTree.c:585
void Dsd_TreeNodeGetInfoOne(Dsd_Node_t *pNode, int *DepthMax, int *GateSizeMax)
Definition dsdTree.c:183
int Dsd_TreeCountPrimeNodes(Dsd_Manager_t *pDsdMan)
Definition dsdTree.c:389
int Dsd_TreeNonDsdMax_rec(Dsd_Node_t *pNode)
Definition dsdTree.c:641
int Dsd_TreeCountNonTerminalNodes(Dsd_Manager_t *pDsdMan)
Definition dsdTree.c:310
word Dsd_TreeFunc2Truth_rec(DdManager *dd, DdNode *bFunc)
Definition dsdTree.c:1026
Dsd_Node_t * Dsd_TreeNodeCreate(int Type, int nDecs, int BlockNum)
FUNCTION DEFINITIONS ///.
Definition dsdTree.c:61
void Dsd_TreePrint(FILE *pFile, Dsd_Manager_t *pDsdMan, char *pInputNames[], char *pOutputNames[], int fShortNames, int Output, int OffSet)
Definition dsdTree.c:830
void Dsd_TreeNodeDelete(DdManager *dd, Dsd_Node_t *pNode)
Definition dsdTree.c:87
int Dsd_TreeCountNonTerminalNodesOne(Dsd_Node_t *pRoot)
Definition dsdTree.c:331
int Dsd_TreeSuppSize(Dsd_Manager_t *pDsdMan, int Output)
Definition dsdTree.c:693
int Dsd_TreeCollectDecomposableVars(Dsd_Manager_t *pDsdMan, int *pVars)
Definition dsdTree.c:470
void Dsd_TreePrint2_rec(FILE *pFile, DdManager *dd, Dsd_Node_t *pNode, int fComp, char *pInputNames[])
Definition dsdTree.c:1042
Dsd_Node_t ** Dsd_TreeCollectNodesDfs(Dsd_Manager_t *pDsdMan, int *pnNodes)
Definition dsdTree.c:555
void Dsd_TreePrint4_rec(Vec_Str_t *p, Dsd_Node_t *pNode)
Definition dsdTree.c:775
void Dsd_TreePrint4(void *pStr, Dsd_Manager_t *pDsdMan, int Output)
Definition dsdTree.c:803
int Dsd_TreeGetAigCost(Dsd_Node_t *pNode)
Definition dsdTree.c:291
void Dsd_TreePrint2(FILE *pFile, Dsd_Manager_t *pDsdMan, char *pInputNames[], char *pOutputNames[], int Output)
Definition dsdTree.c:1106
void Dsd_TreePrint3(void *pStr, Dsd_Manager_t *pDsdMan, int Output)
Definition dsdTree.c:748
void Dsd_NodePrint(FILE *pFile, Dsd_Node_t *pNode)
Definition dsdTree.c:1138
void Dsd_TreeNodeGetInfo(Dsd_Manager_t *pDsdMan, int *DepthMax, int *GateSizeMax)
Definition dsdTree.c:156
void Dsd_TreeUnmark(Dsd_Manager_t *pDsdMan)
Definition dsdTree.c:107
int Dsd_TreeSuppSize_rec(Dsd_Node_t *pNode)
Definition dsdTree.c:682
DdNode * Dsd_TreeGetPrimeFunctionOld(DdManager *dd, Dsd_Node_t *pNode, int fRemap)
Definition dsdTree.c:1309
int Dsd_TreeNonDsdMax(Dsd_Manager_t *pDsdMan, int Output)
Definition dsdTree.c:655
int Dsd_TreeGetAigCost_rec(Dsd_Node_t *pNode)
Definition dsdTree.c:255
enum Dsd_Type_t_ Dsd_Type_t
Definition dsd.h:61
struct Dsd_Manager_t_ Dsd_Manager_t
TYPEDEF DEFINITIONS ///.
Definition dsd.h:59
struct Dsd_Node_t_ Dsd_Node_t
Definition dsd.h:60
DdNode * Dsd_TreeGetPrimeFunction(DdManager *dd, Dsd_Node_t *pNode)
FUNCTION DEFINITIONS ///.
Definition dsdLocal.c:54
#define Dsd_Regular(p)
Definition dsd.h:69
@ DSD_NODE_EXOR
Definition dsd.h:51
@ DSD_NODE_OR
Definition dsd.h:50
@ DSD_NODE_PRIME
Definition dsd.h:52
@ DSD_NODE_CONST1
Definition dsd.h:48
@ DSD_NODE_BUF
Definition dsd.h:49
#define Dsd_IsComplement(p)
MACRO DEFINITIONS ///.
Definition dsd.h:68
Cube * p
Definition exorList.c:222
DdNode * Extra_bddFindOneCube(DdManager *dd, DdNode *bF)
void Extra_PrintSymbols(FILE *pFile, char Char, int nTimes, int fPrintNewLine)
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
DdManager * dd
Definition dsdInt.h:42
Dsd_Node_t ** pRoots
Definition dsdInt.h:48
DdNode * G
Definition dsdInt.h:57
Dsd_Type_t Type
Definition dsdInt.h:56
short nVisits
Definition dsdInt.h:62
DdNode * S
Definition dsdInt.h:58
Dsd_Node_t ** pDecs
Definition dsdInt.h:59
short nDecs
Definition dsdInt.h:61
#define assert(ex)
Definition util_old.h:213
char * memset()
char * sprintf()