00001
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include <time.h>
00025
00026 #include "extra.h"
00027 #include "cas.h"
00028
00032
00033 DdNode * GetSingleOutputFunction( DdManager * dd, DdNode ** pbOuts, int nOuts, DdNode ** pbVarsEnc, int nVarsEnc, int fVerbose );
00034 DdNode * GetSingleOutputFunctionRemapped( DdManager * dd, DdNode ** pOutputs, int nOuts, DdNode ** pbVarsEnc, int nVarsEnc );
00035 DdNode * GetSingleOutputFunctionRemappedNewDD( DdManager * dd, DdNode ** pOutputs, int nOuts, DdManager ** DdNew );
00036
00037 extern int CreateDecomposedNetwork( DdManager * dd, DdNode * aFunc, char ** pNames, int nNames, char * FileName, int nLutSize, int fCheck, int fVerbose );
00038
00039 void WriteSingleOutputFunctionBlif( DdManager * dd, DdNode * aFunc, char ** pNames, int nNames, char * FileName );
00040
00041 DdNode * Cudd_bddTransferPermute( DdManager * ddSource, DdManager * ddDestination, DdNode * f, int * Permute );
00042
00046
00047
00048
00049
00053
00054 #define PRD(p) printf( "\nDECOMPOSITION TREE:\n\n" ); PrintDecEntry( (p), 0 )
00055 #define PRB(f) printf( #f " = " ); Cudd_bddPrint(dd,f); printf( "\n" )
00056 #define PRK(f,n) Cudd_PrintKMap(stdout,dd,(f),Cudd_Not(f),(n),NULL,0); printf( "K-map for function" #f "\n\n" )
00057 #define PRK2(f,g,n) Cudd_PrintKMap(stdout,dd,(f),(g),(n),NULL,0); printf( "K-map for function <" #f ", " #g ">\n\n" )
00058
00059
00063
00075 int Abc_CascadeExperiment( char * pFileGeneric, DdManager * dd, DdNode ** pOutputs, int nInputs, int nOutputs, int nLutSize, int fCheck, int fVerbose )
00076 {
00077 int i;
00078 int nVars = nInputs;
00079 int nOuts = nOutputs;
00080 long clk1;
00081
00082 int nVarsEnc;
00083 DdNode * pbVarsEnc[MAXOUTPUTS];
00084
00085 int nNames;
00086 char * pNames[MAXINPUTS];
00087
00088 DdNode * aFunc;
00089
00090 char FileNameIni[100];
00091 char FileNameFin[100];
00092 char Buffer[100];
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102 strcpy( FileNameIni, pFileGeneric );
00103 strcat( FileNameIni, "_ENC.blif" );
00104
00105 strcpy( FileNameFin, pFileGeneric );
00106 strcat( FileNameFin, "_LUT.blif" );
00107
00108
00109
00110 nVarsEnc = Extra_Base2Log( nOuts );
00111 for ( i = 0; i < nVarsEnc; i++ )
00112 pbVarsEnc[i] = Cudd_bddNewVarAtLevel( dd, i );
00113
00114
00115
00116 nNames = nVars + nVarsEnc;
00117 for ( i = 0; i < nVars; i++ )
00118 {
00119
00120 sprintf( Buffer, "pi%03d", i );
00121 pNames[i] = Extra_UtilStrsav( Buffer );
00122 }
00123
00124 for ( ; i < nNames; i++ )
00125 {
00126 sprintf( Buffer, "OutEnc_%02d", i-nVars );
00127 pNames[i] = Extra_UtilStrsav( Buffer );
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 clk1 = clock();
00140 aFunc = GetSingleOutputFunction( dd, pOutputs, nOuts, pbVarsEnc, nVarsEnc, fVerbose ); Cudd_Ref( aFunc );
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 clk1 = clock();
00155
00156
00157
00158 Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1);
00159 Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1);
00160
00161
00162
00163
00164 if ( fVerbose )
00165 printf( "MTBDD reordered = %6d nodes\n", Cudd_DagSize( aFunc ) );
00166 if ( fVerbose )
00167 printf( "Variable reordering time = %.2f sec\n", (float)(clock() - clk1)/(float)(CLOCKS_PER_SEC) );
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 clk1 = clock();
00178 if ( fCheck )
00179 WriteSingleOutputFunctionBlif( dd, aFunc, pNames, nNames, FileNameIni );
00180
00181
00182
00183
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00215
00216
00217 if ( !CreateDecomposedNetwork( dd, aFunc, pNames, nNames, FileNameFin, nLutSize, fCheck, fVerbose ) )
00218 return 0;
00219
00220
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00252
00253
00254
00255 if ( fCheck )
00256 {
00257 extern int Cmd_CommandExecute( void * pAbc, char * sCommand );
00258 extern void * Abc_FrameGetGlobalFrame();
00259 char Command[200];
00260 sprintf( Command, "cec %s %s", FileNameIni, FileNameFin );
00261 Cmd_CommandExecute( Abc_FrameGetGlobalFrame(), Command );
00262 }
00263
00264 Cudd_RecursiveDeref( dd, aFunc );
00265
00266
00267 for ( i = 0; i < nNames; i++ )
00268 free( pNames[i] );
00269
00270
00271
00272
00273
00274 return 1;
00275 }
00276
00277 #if 0
00278
00290 void Experiment2( BFunc * pFunc )
00291 {
00292 int i, x, RetValue;
00293 int nVars = pFunc->nInputs;
00294 int nOuts = pFunc->nOutputs;
00295 DdManager * dd = pFunc->dd;
00296 long clk1;
00297
00298
00299
00300
00301 int nNames;
00302 char * pNames[MAXINPUTS];
00303
00304 DdNode * aFunc;
00305
00306 char FileNameIni[100];
00307 char FileNameFin[100];
00308 char Buffer[100];
00309
00310 DdManager * DdNew;
00311
00312
00313
00314
00315
00316
00317
00318
00319 strcpy( FileNameIni, pFunc->FileGeneric );
00320 strcat( FileNameIni, "_ENC.blif" );
00321
00322 strcpy( FileNameFin, pFunc->FileGeneric );
00323 strcat( FileNameFin, "_LUT.blif" );
00324
00325
00326 clk1 = clock();
00327
00328 aFunc = GetSingleOutputFunctionRemappedNewDD( dd, pFunc->pOutputs, nOuts, &DdNew ); Cudd_Ref( aFunc );
00329 printf( "Single-output function derivation time = %.2f sec\n", (float)(clock() - clk1)/(float)(CLOCKS_PER_SEC) );
00330
00331
00332
00333 Extra_Dissolve( pFunc );
00334
00335
00336 printf( "\nReordering variables in the new manager...\n");
00337 clk1 = clock();
00338 printf( "Node count before = %d\n", Cudd_DagSize( aFunc ) );
00339
00340 Cudd_ReduceHeap(DdNew, CUDD_REORDER_SYMM_SIFT,1);
00341
00342 printf( "Node count after = %d\n", Cudd_DagSize( aFunc ) );
00343 printf( "Variable reordering time = %.2f sec\n", (float)(clock() - clk1)/(float)(CLOCKS_PER_SEC) );
00344 printf( "\n" );
00345
00346
00347
00348
00349
00350
00351 nNames = DdNew->size;
00352 for ( x = 0; x < nNames; x++ )
00353 {
00354 sprintf( Buffer, "v%02d", x );
00355 pNames[x] = Extra_UtilStrsav( Buffer );
00356 }
00357
00358
00359
00360
00361 clk1 = clock();
00362 WriteSingleOutputFunctionBlif( DdNew, aFunc, pNames, nNames, FileNameIni );
00363 printf( "Single-output function writing time = %.2f sec\n", (float)(clock() - clk1)/(float)(CLOCKS_PER_SEC) );
00364
00365
00367
00368 clk1 = clock();
00369 {
00370 BFunc g_Func;
00371 DdNode * aRes;
00372
00373 g_Func.dd = DdNew;
00374 g_Func.FileInput = Extra_UtilStrsav(FileNameIni);
00375
00376 if ( Extra_ReadFile( &g_Func ) == 0 )
00377 {
00378 printf( "\nSomething did not work out while reading the input file for verification\n");
00379 Extra_Dissolve( &g_Func );
00380 return;
00381 }
00382
00383 aRes = Cudd_BddToAdd( DdNew, g_Func.pOutputs[0] ); Cudd_Ref( aRes );
00384
00385 if ( aRes != aFunc )
00386 printf( "\nVerification FAILED!\n");
00387 else
00388 printf( "\nVerification okay!\n");
00389
00390 Cudd_RecursiveDeref( DdNew, aRes );
00391
00392
00393 Extra_Dissolve( &g_Func );
00394 }
00395 printf( "Preliminary verification time = %.2f sec\n", (float)(clock() - clk1)/(float)(CLOCKS_PER_SEC) );
00397
00398
00399 CreateDecomposedNetwork( DdNew, aFunc, pNames, nNames, FileNameFin, nLutSize, 0 );
00400
00401
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00433
00434
00435
00436 Cudd_RecursiveDeref( DdNew, aFunc );
00437
00438
00439 for ( i = 0; i < nNames; i++ )
00440 free( pNames[i] );
00441
00442
00443
00445
00446 RetValue = Cudd_CheckZeroRef( DdNew );
00447 printf( "\nThe number of referenced nodes in the new manager = %d\n", RetValue );
00448 Cudd_Quit( DdNew );
00449
00450
00451
00452
00453 }
00454
00455 #endif
00456
00460
00461
00462 static unsigned char BitCount8[256] = {
00463 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
00464 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00465 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00466 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00467 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
00468 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00469 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
00470 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
00471 };
00472
00474 static int s_SuppSize[MAXOUTPUTS];
00475 int CompareSupports( int *ptrX, int *ptrY )
00476 {
00477 return ( s_SuppSize[*ptrY] - s_SuppSize[*ptrX] );
00478 }
00480
00481
00483 static int s_MintOnes[MAXOUTPUTS];
00484 int CompareMinterms( int *ptrX, int *ptrY )
00485 {
00486 return ( s_MintOnes[*ptrY] - s_MintOnes[*ptrX] );
00487 }
00489
00490 int GrayCode ( int BinCode )
00491 {
00492 return BinCode ^ ( BinCode >> 1 );
00493 }
00494
00506 DdNode * GetSingleOutputFunction( DdManager * dd, DdNode ** pbOuts, int nOuts, DdNode ** pbVarsEnc, int nVarsEnc, int fVerbose )
00507 {
00508 int i;
00509 DdNode * bResult, * aResult;
00510 DdNode * bCube, * bTemp, * bProd;
00511
00512 int Order[MAXOUTPUTS];
00513
00514
00515
00516 for ( i = 0; i < nOuts; i++ )
00517 {
00518 s_SuppSize[i] = Cudd_SupportSize( dd, pbOuts[i] );
00519
00520 Order[i] = i;
00521
00522 }
00523
00524
00525 qsort( (void*)Order, nOuts, sizeof(int), (int(*)(const void*, const void*)) CompareSupports );
00526
00527
00528
00529
00530 bResult = b0; Cudd_Ref( bResult );
00531 for ( i = 0; i < nOuts; i++ )
00532 {
00533
00534
00535 bCube = Extra_bddBitsToCube( dd, i, nVarsEnc, pbVarsEnc, 1 ); Cudd_Ref( bCube );
00536 bProd = Cudd_bddAnd( dd, bCube, pbOuts[Order[i]] ); Cudd_Ref( bProd );
00537 Cudd_RecursiveDeref( dd, bCube );
00538
00539 bResult = Cudd_bddOr( dd, bProd, bTemp = bResult ); Cudd_Ref( bResult );
00540 Cudd_RecursiveDeref( dd, bTemp );
00541 Cudd_RecursiveDeref( dd, bProd );
00542 }
00543
00544
00545 if ( fVerbose )
00546 printf( "Single BDD size = %6d nodes\n", Cudd_DagSize(bResult) );
00547 aResult = Cudd_BddToAdd( dd, bResult ); Cudd_Ref( aResult );
00548 Cudd_RecursiveDeref( dd, bResult );
00549 if ( fVerbose )
00550 printf( "MTBDD = %6d nodes\n", Cudd_DagSize(aResult) );
00551 Cudd_Deref( aResult );
00552 return aResult;
00553 }
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00587
00588
00600 DdNode * GetSingleOutputFunctionRemapped( DdManager * dd, DdNode ** pOutputs, int nOuts, DdNode ** pbVarsEnc, int nVarsEnc )
00601
00602 {
00603 static int Permute[MAXINPUTS];
00604 static DdNode * pRemapped[MAXOUTPUTS];
00605
00606 DdNode * bSupp, * bTemp;
00607 int i, Counter;
00608 int nSuppPrev = -1;
00609 DdNode * bFunc;
00610 DdNode * aFunc;
00611
00612 Cudd_AutodynDisable(dd);
00613
00614
00615 for ( i = 0; i < nOuts; i++ )
00616 {
00617
00618 bSupp = Cudd_Support( dd, pOutputs[i] ); Cudd_Ref( bSupp );
00619
00620
00621 Counter = 0;
00622 for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
00623 Permute[bTemp->index] = Counter++;
00624
00625
00626 pRemapped[i] = Cudd_bddPermute( dd, pOutputs[i], Permute ); Cudd_Ref( pRemapped[i] );
00627
00628
00629 Cudd_RecursiveDeref( dd, bSupp );
00630 }
00631
00632
00633 bFunc = Extra_bddEncodingBinary( dd, pRemapped, nOuts, pbVarsEnc, nVarsEnc ); Cudd_Ref( bFunc );
00634
00635
00636 aFunc = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( aFunc );
00637 Cudd_RecursiveDeref( dd, bFunc );
00638
00639
00640 for ( i = 0; i < nOuts; i++ )
00641 Cudd_RecursiveDeref( dd, pRemapped[i] );
00642
00643 Cudd_Deref( aFunc );
00644 return aFunc;
00645 }
00646
00647
00659 DdNode * GetSingleOutputFunctionRemappedNewDD( DdManager * dd, DdNode ** pOutputs, int nOuts, DdManager ** DdNew )
00660
00661 {
00662 static int Permute[MAXINPUTS];
00663 static DdNode * pRemapped[MAXOUTPUTS];
00664
00665 static DdNode * pbVarsEnc[MAXINPUTS];
00666 int nVarsEnc;
00667
00668 DdManager * ddnew;
00669
00670 DdNode * bSupp, * bTemp;
00671 int i, v, Counter;
00672 int nSuppPrev = -1;
00673 DdNode * bFunc;
00674
00675
00676 DdNode * bFuncNew;
00677 DdNode * aFuncNew;
00678
00679 int nVarsMax = 0;
00680
00681
00682 for ( i = 0; i < nOuts; i++ )
00683 {
00684
00685 bSupp = Cudd_Support( dd, pOutputs[i] ); Cudd_Ref( bSupp );
00686
00687
00688
00689 Counter = 0;
00690 for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
00691 Permute[bTemp->index] = dd->invperm[Counter++];
00692
00693
00694 pRemapped[i] = Cudd_bddPermute( dd, pOutputs[i], Permute ); Cudd_Ref( pRemapped[i] );
00695
00696
00697 Cudd_RecursiveDeref( dd, bSupp );
00698
00699
00700
00701 if ( nVarsMax < Counter )
00702 nVarsMax = Counter;
00703 }
00704
00705
00706 nVarsEnc = Extra_Base2Log(nOuts);
00707
00708
00709
00710
00711
00712
00713
00714
00715 for ( v = 0; v < nVarsEnc; v++ )
00716 pbVarsEnc[v] = Cudd_bddNewVarAtLevel( dd, v );
00717
00718
00719
00720
00721
00722
00723 bFunc = Extra_bddEncodingBinary( dd, pRemapped, nOuts, pbVarsEnc, nVarsEnc ); Cudd_Ref( bFunc );
00724
00725
00726
00727
00728
00729 for ( v = 0; v < nVarsMax + nVarsEnc; v++ )
00730 Permute[dd->invperm[v]] = v;
00731
00732
00734
00735 ddnew = Cudd_Init( nVarsMax + nVarsEnc, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
00736
00737 Cudd_AutodynEnable(dd, CUDD_REORDER_SYMM_SIFT);
00738
00739
00740 bFuncNew = Cudd_bddTransferPermute( dd, ddnew, bFunc, Permute ); Cudd_Ref( bFuncNew );
00742
00743
00744
00745 Cudd_RecursiveDeref( dd, bFunc );
00746 for ( i = 0; i < nOuts; i++ )
00747 Cudd_RecursiveDeref( dd, pRemapped[i] );
00748
00749
00751
00752 aFuncNew = Cudd_BddToAdd( ddnew, bFuncNew ); Cudd_Ref( aFuncNew );
00753 Cudd_RecursiveDeref( ddnew, bFuncNew );
00754
00755
00756 *DdNew = ddnew;
00758
00759 Cudd_Deref( aFuncNew );
00760 return aFuncNew;
00761 }
00762
00766
00767 void WriteDDintoBLIFfile( FILE * pFile, DdNode * Func, char * OutputName, char * Prefix, char ** InputNames );
00768
00769
00781 void WriteSingleOutputFunctionBlif( DdManager * dd, DdNode * aFunc, char ** pNames, int nNames, char * FileName )
00782 {
00783 int i;
00784 FILE * pFile;
00785
00786
00787 pFile = fopen( FileName, "w" );
00788 fprintf( pFile, ".model %s\n", FileName );
00789
00790 fprintf( pFile, ".inputs" );
00791 for ( i = 0; i < nNames; i++ )
00792 fprintf( pFile, " %s", pNames[i] );
00793 fprintf( pFile, "\n" );
00794 fprintf( pFile, ".outputs F" );
00795 fprintf( pFile, "\n" );
00796
00797
00798 WriteDDintoBLIFfile( pFile, aFunc, "F", "", pNames );
00799
00800 fprintf( pFile, ".end\n" );
00801 fclose( pFile );
00802 }
00803
00815 void WriteDDintoBLIFfile( FILE * pFile, DdNode * Func, char * OutputName, char * Prefix, char ** InputNames )
00816
00817
00818
00819
00820
00821
00822 {
00823 int i;
00824 st_table * visited;
00825 st_generator * gen = NULL;
00826 long refAddr, diff, mask;
00827 DdNode * Node, * Else, * ElseR, * Then;
00828
00829
00830 visited = st_init_table( st_ptrcmp, st_ptrhash );
00831
00832
00833 cuddCollectNodes( Cudd_Regular(Func), visited );
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 refAddr = ( long )Cudd_Regular(Func);
00848 diff = 0;
00849 gen = st_init_gen( visited );
00850 while ( st_gen( gen, ( char ** ) &Node, NULL ) )
00851 {
00852 diff |= refAddr ^ ( long ) Node;
00853 }
00854 st_free_gen( gen );
00855 gen = NULL;
00856
00857
00858 for ( i = 0; ( unsigned ) i < 8 * sizeof( long ); i += 4 )
00859 {
00860 mask = ( 1 << i ) - 1;
00861 if ( diff <= mask )
00862 break;
00863 }
00864
00865
00866
00867 fprintf( pFile, ".names %s%lx %s\n", Prefix, ( mask & (long)Cudd_Regular(Func) ) / sizeof(DdNode), OutputName );
00868 fprintf( pFile, "%s 1\n", (Cudd_IsComplement(Func))? "0": "1" );
00869
00870
00871 gen = st_init_gen( visited );
00872 while ( st_gen( gen, ( char ** ) &Node, NULL ) )
00873 {
00874 if ( Node->index == CUDD_MAXINDEX )
00875 {
00876
00877 fprintf( pFile, ".names %s%lx\n", Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
00878 fprintf( pFile, " %s\n", (cuddV(Node) == 0.0)? "0": "1" );
00879 continue;
00880 }
00881
00882 Else = cuddE(Node);
00883 ElseR = Cudd_Regular(Else);
00884 Then = cuddT(Node);
00885
00886 assert( InputNames[Node->index] );
00887 if ( Else == ElseR )
00888 {
00889 fprintf( pFile, ".names %s %s%lx %s%lx %s%lx\n", InputNames[Node->index],
00890 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
00891 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
00892 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
00893 fprintf( pFile, "01- 1\n" );
00894 fprintf( pFile, "1-1 1\n" );
00895 }
00896 else
00897 {
00898 int * pSlot;
00899 fprintf( pFile, ".names %s %s%lx_i %s%lx %s%lx\n", InputNames[Node->index],
00900 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
00901 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
00902 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
00903 fprintf( pFile, "01- 1\n" );
00904 fprintf( pFile, "1-1 1\n" );
00905
00906
00907 if ( !st_find( visited, (char *)ElseR, (char ***)&pSlot ) )
00908 assert( 0 );
00909 if ( *pSlot )
00910 continue;
00911 *pSlot = 1;
00912
00913 fprintf( pFile, ".names %s%lx %s%lx_i\n",
00914 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
00915 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode) );
00916 fprintf( pFile, "0 1\n" );
00917 }
00918 }
00919 st_free_gen( gen );
00920 gen = NULL;
00921 st_free_table( visited );
00922 }
00923
00924
00925
00926
00927 static DdManager * s_ddmin;
00928
00940 void WriteDDintoBLIFfileReorder( DdManager * dd, FILE * pFile, DdNode * Func, char * OutputName, char * Prefix, char ** InputNames )
00941
00942
00943
00944
00945
00946
00947 {
00948 int i;
00949 st_table * visited;
00950 st_generator * gen = NULL;
00951 long refAddr, diff, mask;
00952 DdNode * Node, * Else, * ElseR, * Then;
00953
00954
00956 DdNode * bFmin;
00957 int clk1;
00958
00959 if ( s_ddmin == NULL )
00960 s_ddmin = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
00961
00962 clk1 = clock();
00963 bFmin = Cudd_bddTransfer( dd, s_ddmin, Func ); Cudd_Ref( bFmin );
00964
00965
00966 printf( "Nodes before = %d. ", Cudd_DagSize(bFmin) );
00967 Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SYMM_SIFT,1);
00968
00969 printf( "Nodes after = %d. \n", Cudd_DagSize(bFmin) );
00971
00972
00973
00974
00975 visited = st_init_table( st_ptrcmp, st_ptrhash );
00976
00977
00978 cuddCollectNodes( Cudd_Regular(bFmin), visited );
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992 refAddr = ( long )Cudd_Regular(bFmin);
00993 diff = 0;
00994 gen = st_init_gen( visited );
00995 while ( st_gen( gen, ( char ** ) &Node, NULL ) )
00996 {
00997 diff |= refAddr ^ ( long ) Node;
00998 }
00999 st_free_gen( gen );
01000 gen = NULL;
01001
01002
01003 for ( i = 0; ( unsigned ) i < 8 * sizeof( long ); i += 4 )
01004 {
01005 mask = ( 1 << i ) - 1;
01006 if ( diff <= mask )
01007 break;
01008 }
01009
01010
01011
01012 fprintf( pFile, ".names %s%lx %s\n", Prefix, ( mask & (long)Cudd_Regular(bFmin) ) / sizeof(DdNode), OutputName );
01013 fprintf( pFile, "%s 1\n", (Cudd_IsComplement(bFmin))? "0": "1" );
01014
01015
01016 gen = st_init_gen( visited );
01017 while ( st_gen( gen, ( char ** ) &Node, NULL ) )
01018 {
01019 if ( Node->index == CUDD_MAXINDEX )
01020 {
01021
01022 fprintf( pFile, ".names %s%lx\n", Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
01023 fprintf( pFile, " %s\n", (cuddV(Node) == 0.0)? "0": "1" );
01024 continue;
01025 }
01026
01027 Else = cuddE(Node);
01028 ElseR = Cudd_Regular(Else);
01029 Then = cuddT(Node);
01030
01031 assert( InputNames[Node->index] );
01032 if ( Else == ElseR )
01033 {
01034 fprintf( pFile, ".names %s %s%lx %s%lx %s%lx\n", InputNames[Node->index],
01035 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
01036 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
01037 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
01038 fprintf( pFile, "01- 1\n" );
01039 fprintf( pFile, "1-1 1\n" );
01040 }
01041 else
01042 {
01043 fprintf( pFile, ".names %s %s%lx_i %s%lx %s%lx\n", InputNames[Node->index],
01044 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
01045 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
01046 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
01047 fprintf( pFile, "01- 1\n" );
01048 fprintf( pFile, "1-1 1\n" );
01049
01050 fprintf( pFile, ".names %s%lx %s%lx_i\n",
01051 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
01052 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode) );
01053 fprintf( pFile, "0 1\n" );
01054 }
01055 }
01056 st_free_gen( gen );
01057 gen = NULL;
01058 st_free_table( visited );
01059
01060
01062 Cudd_RecursiveDeref( s_ddmin, bFmin );
01064 }
01065
01066
01067
01068
01072 static DdNode * cuddBddTransferPermuteRecur
01073 ARGS((DdManager * ddS, DdManager * ddD, DdNode * f, st_table * table, int * Permute ));
01074
01075 static DdNode * cuddBddTransferPermute
01076 ARGS((DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute));
01077
01093 DdNode *
01094 Cudd_bddTransferPermute( DdManager * ddSource,
01095 DdManager * ddDestination, DdNode * f, int * Permute )
01096 {
01097 DdNode *res;
01098 do
01099 {
01100 ddDestination->reordered = 0;
01101 res = cuddBddTransferPermute( ddSource, ddDestination, f, Permute );
01102 }
01103 while ( ddDestination->reordered == 1 );
01104 return ( res );
01105
01106 }
01107
01108
01109
01110
01111
01112
01113
01127 DdNode *
01128 cuddBddTransferPermute( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute )
01129 {
01130 DdNode *res;
01131 st_table *table = NULL;
01132 st_generator *gen = NULL;
01133 DdNode *key, *value;
01134
01135 table = st_init_table( st_ptrcmp, st_ptrhash );
01136 if ( table == NULL )
01137 goto failure;
01138 res = cuddBddTransferPermuteRecur( ddS, ddD, f, table, Permute );
01139 if ( res != NULL )
01140 cuddRef( res );
01141
01142
01143
01144
01145 gen = st_init_gen( table );
01146 if ( gen == NULL )
01147 goto failure;
01148 while ( st_gen( gen, ( char ** ) &key, ( char ** ) &value ) )
01149 {
01150 Cudd_RecursiveDeref( ddD, value );
01151 }
01152 st_free_gen( gen );
01153 gen = NULL;
01154 st_free_table( table );
01155 table = NULL;
01156
01157 if ( res != NULL )
01158 cuddDeref( res );
01159 return ( res );
01160
01161 failure:
01162 if ( table != NULL )
01163 st_free_table( table );
01164 if ( gen != NULL )
01165 st_free_gen( gen );
01166 return ( NULL );
01167
01168 }
01169
01170
01183 static DdNode *
01184 cuddBddTransferPermuteRecur( DdManager * ddS,
01185 DdManager * ddD, DdNode * f, st_table * table, int * Permute )
01186 {
01187 DdNode *ft, *fe, *t, *e, *var, *res;
01188 DdNode *one, *zero;
01189 int index;
01190 int comple = 0;
01191
01192 statLine( ddD );
01193 one = DD_ONE( ddD );
01194 comple = Cudd_IsComplement( f );
01195
01196
01197 if ( Cudd_IsConstant( f ) )
01198 return ( Cudd_NotCond( one, comple ) );
01199
01200
01201 f = Cudd_NotCond( f, comple );
01202
01203
01204
01205 if ( st_lookup( table, ( char * ) f, ( char ** ) &res ) )
01206 return ( Cudd_NotCond( res, comple ) );
01207
01208
01209 index = Permute[f->index];
01210 ft = cuddT( f );
01211 fe = cuddE( f );
01212
01213 t = cuddBddTransferPermuteRecur( ddS, ddD, ft, table, Permute );
01214 if ( t == NULL )
01215 {
01216 return ( NULL );
01217 }
01218 cuddRef( t );
01219
01220 e = cuddBddTransferPermuteRecur( ddS, ddD, fe, table, Permute );
01221 if ( e == NULL )
01222 {
01223 Cudd_RecursiveDeref( ddD, t );
01224 return ( NULL );
01225 }
01226 cuddRef( e );
01227
01228 zero = Cudd_Not( one );
01229 var = cuddUniqueInter( ddD, index, one, zero );
01230 if ( var == NULL )
01231 {
01232 Cudd_RecursiveDeref( ddD, t );
01233 Cudd_RecursiveDeref( ddD, e );
01234 return ( NULL );
01235 }
01236 res = cuddBddIteRecur( ddD, var, t, e );
01237 if ( res == NULL )
01238 {
01239 Cudd_RecursiveDeref( ddD, t );
01240 Cudd_RecursiveDeref( ddD, e );
01241 return ( NULL );
01242 }
01243 cuddRef( res );
01244 Cudd_RecursiveDeref( ddD, t );
01245 Cudd_RecursiveDeref( ddD, e );
01246
01247 if ( st_add_direct( table, ( char * ) f, ( char * ) res ) ==
01248 ST_OUT_OF_MEM )
01249 {
01250 Cudd_RecursiveDeref( ddD, res );
01251 return ( NULL );
01252 }
01253 return ( Cudd_NotCond( res, comple ) );
01254
01255 }
01256
01260
01261
01262
01263