ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
casCore.c
Go to the documentation of this file.
1
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include "base/main/main.h"
26#include "base/cmd/cmd.h"
27#include "bdd/extrab/extraBdd.h"
28#include "cas.h"
29
31
32
36
37DdNode * GetSingleOutputFunction( DdManager * dd, DdNode ** pbOuts, int nOuts, DdNode ** pbVarsEnc, int nVarsEnc, int fVerbose );
38DdNode * GetSingleOutputFunctionRemapped( DdManager * dd, DdNode ** pOutputs, int nOuts, DdNode ** pbVarsEnc, int nVarsEnc );
39DdNode * GetSingleOutputFunctionRemappedNewDD( DdManager * dd, DdNode ** pOutputs, int nOuts, DdManager ** DdNew );
40
41extern int CreateDecomposedNetwork( DdManager * dd, DdNode * aFunc, char ** pNames, int nNames, char * FileName, int nLutSize, int fCheck, int fVerbose );
42
43void WriteSingleOutputFunctionBlif( DdManager * dd, DdNode * aFunc, char ** pNames, int nNames, char * FileName );
44
45DdNode * Cudd_bddTransferPermute( DdManager * ddSource, DdManager * ddDestination, DdNode * f, int * Permute );
46
50
51//static FILE * pTable = NULL;
52//static long s_RemappingTime = 0;
53
57
58#define PRD(p) printf( "\nDECOMPOSITION TREE:\n\n" ); PrintDecEntry( (p), 0 )
59#define PRB_(f) printf( #f " = " ); Cudd_bddPrint(dd,f); printf( "\n" )
60#define PRK(f,n) Cudd_PrintKMap(stdout,dd,(f),Cudd_Not(f),(n),NULL,0); printf( "K-map for function" #f "\n\n" )
61#define PRK2(f,g,n) Cudd_PrintKMap(stdout,dd,(f),(g),(n),NULL,0); printf( "K-map for function <" #f ", " #g ">\n\n" )
62
63
67
79int Abc_CascadeExperiment( char * pFileGeneric, DdManager * dd, DdNode ** pOutputs, int nInputs, int nOutputs, int nLutSize, int fCheck, int fVerbose )
80{
81 int i;
82 int nVars = nInputs;
83 int nOuts = nOutputs;
84 abctime clk1;
85
86 int nVarsEnc; // the number of additional variables to encode outputs
87 DdNode * pbVarsEnc[MAXOUTPUTS]; // the BDDs of the encoding vars
88
89 int nNames; // the total number of all inputs
90 char * pNames[MAXINPUTS]; // the temporary storage for the input (and output encoding) names
91
92 DdNode * aFunc; // the encoded 0-1 BDD containing all the outputs
93
94 char FileNameIni[100];
95 char FileNameFin[100];
96 char Buffer[100];
97
98
99//pTable = fopen( "stats.txt", "a+" );
100//fprintf( pTable, "%s ", pFileGeneric );
101//fprintf( pTable, "%d ", nVars );
102//fprintf( pTable, "%d ", nOuts );
103
104
105 // assign the file names
106 strcpy( FileNameIni, pFileGeneric );
107 strcat( FileNameIni, "_ENC.blif" );
108
109 strcpy( FileNameFin, pFileGeneric );
110 strcat( FileNameFin, "_LUT.blif" );
111
112
113 // create the variables to encode the outputs
114 nVarsEnc = Abc_Base2Log( nOuts );
115 for ( i = 0; i < nVarsEnc; i++ )
116 pbVarsEnc[i] = Cudd_bddNewVarAtLevel( dd, i );
117
118
119 // store the input names
120 nNames = nVars + nVarsEnc;
121 for ( i = 0; i < nVars; i++ )
122 {
123// pNames[i] = Extra_UtilStrsav( pFunc->pInputNames[i] );
124 sprintf( Buffer, "pi%03d", i );
125 pNames[i] = Extra_UtilStrsav( Buffer );
126 }
127 // set the encoding variable name
128 for ( ; i < nNames; i++ )
129 {
130 sprintf( Buffer, "OutEnc_%02d", i-nVars );
131 pNames[i] = Extra_UtilStrsav( Buffer );
132 }
133
134
135 // print the variable order
136// printf( "\n" );
137// printf( "Variable order is: " );
138// for ( i = 0; i < dd->size; i++ )
139// printf( " %d", dd->invperm[i] );
140// printf( "\n" );
141
142 // derive the single-output function
143 clk1 = Abc_Clock();
144 aFunc = GetSingleOutputFunction( dd, pOutputs, nOuts, pbVarsEnc, nVarsEnc, fVerbose ); Cudd_Ref( aFunc );
145// aFunc = GetSingleOutputFunctionRemapped( dd, pOutputs, nOuts, pbVarsEnc, nVarsEnc ); Cudd_Ref( aFunc );
146// if ( fVerbose )
147// printf( "Single-output function computation time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
148
149//fprintf( pTable, "%d ", Cudd_SharingSize( pOutputs, nOutputs ) );
150//fprintf( pTable, "%d ", Extra_ProfileWidthSharingMax(dd, pOutputs, nOutputs) );
151
152 // dispose of the multiple-output function
153// Extra_Dissolve( pFunc );
154
155 // reorder the single output function
156// if ( fVerbose )
157// printf( "Reordering variables...\n");
158 clk1 = Abc_Clock();
159// if ( fVerbose )
160// printf( "Node count before = %6d\n", Cudd_DagSize( aFunc ) );
161// Cudd_ReduceHeap(dd, CUDD_REORDER_SIFT,1);
162 Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1);
163 Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1);
164// Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1);
165// Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1);
166// Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1);
167// Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1);
168 if ( fVerbose )
169 printf( "MTBDD reordered = %6d nodes\n", Cudd_DagSize( aFunc ) );
170 if ( fVerbose )
171 printf( "Variable reordering time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
172// printf( "\n" );
173// printf( "Variable order is: " );
174// for ( i = 0; i < dd->size; i++ )
175// printf( " %d", dd->invperm[i] );
176// printf( "\n" );
177//fprintf( pTable, "%d ", Cudd_DagSize( aFunc ) );
178//fprintf( pTable, "%d ", Extra_ProfileWidthMax(dd, aFunc) );
179
180 // write the single-output function into BLIF for verification
181 clk1 = Abc_Clock();
182 if ( fCheck )
183 WriteSingleOutputFunctionBlif( dd, aFunc, pNames, nNames, FileNameIni );
184// if ( fVerbose )
185// printf( "Single-output function writing time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
186
187/*
189 // verification of single output function
190 clk1 = Abc_Clock();
191 {
192 BFunc g_Func;
193 DdNode * aRes;
194
195 g_Func.dd = dd;
196 g_Func.FileInput = Extra_UtilStrsav(FileNameIni);
197
198 if ( Extra_ReadFile( &g_Func ) == 0 )
199 {
200 printf( "\nSomething did not work out while reading the input file for verification\n");
201 Extra_Dissolve( &g_Func );
202 return;
203 }
204
205 aRes = Cudd_BddToAdd( dd, g_Func.pOutputs[0] ); Cudd_Ref( aRes );
206
207 if ( aRes != aFunc )
208 printf( "\nVerification FAILED!\n");
209 else
210 printf( "\nVerification okay!\n");
211
212 Cudd_RecursiveDeref( dd, aRes );
213
214 // delocate
215 Extra_Dissolve( &g_Func );
216 }
217 printf( "Preliminary verification time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
219*/
220
221 if ( !CreateDecomposedNetwork( dd, aFunc, pNames, nNames, FileNameFin, nLutSize, fCheck, fVerbose ) )
222 return 0;
223
224/*
226 // verification of the decomposed LUT network
227 clk1 = Abc_Clock();
228 {
229 BFunc g_Func;
230 DdNode * aRes;
231
232 g_Func.dd = dd;
233 g_Func.FileInput = Extra_UtilStrsav(FileNameFin);
234
235 if ( Extra_ReadFile( &g_Func ) == 0 )
236 {
237 printf( "\nSomething did not work out while reading the input file for verification\n");
238 Extra_Dissolve( &g_Func );
239 return;
240 }
241
242 aRes = Cudd_BddToAdd( dd, g_Func.pOutputs[0] ); Cudd_Ref( aRes );
243
244 if ( aRes != aFunc )
245 printf( "\nFinal verification FAILED!\n");
246 else
247 printf( "\nFinal verification okay!\n");
248
249 Cudd_RecursiveDeref( dd, aRes );
250
251 // delocate
252 Extra_Dissolve( &g_Func );
253 }
254 printf( "Final verification time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
256*/
257
258 // verify the results
259 if ( fCheck )
260 {
261 char Command[300];
262 sprintf( Command, "cec %s %s", FileNameIni, FileNameFin );
264 }
265
266 Cudd_RecursiveDeref( dd, aFunc );
267
268 // release the names
269 for ( i = 0; i < nNames; i++ )
270 ABC_FREE( pNames[i] );
271
272
273//fprintf( pTable, "\n" );
274//fclose( pTable );
275
276 return 1;
277}
278
279#if 0
280
292void Experiment2( BFunc * pFunc )
293{
294 int i, x, RetValue;
295 int nVars = pFunc->nInputs;
296 int nOuts = pFunc->nOutputs;
297 DdManager * dd = pFunc->dd;
298 long clk1;
299
300// int nVarsEnc; // the number of additional variables to encode outputs
301// DdNode * pbVarsEnc[MAXOUTPUTS]; // the BDDs of the encoding vars
302
303 int nNames; // the total number of all inputs
304 char * pNames[MAXINPUTS]; // the temporary storage for the input (and output encoding) names
305
306 DdNode * aFunc; // the encoded 0-1 BDD containing all the outputs
307
308 char FileNameIni[100];
309 char FileNameFin[100];
310 char Buffer[100];
311
312 DdManager * DdNew;
313
314//pTable = fopen( "stats.txt", "a+" );
315//fprintf( pTable, "%s ", pFunc->FileGeneric );
316//fprintf( pTable, "%d ", nVars );
317//fprintf( pTable, "%d ", nOuts );
318
319
320 // assign the file names
321 strcpy( FileNameIni, pFunc->FileGeneric );
322 strcat( FileNameIni, "_ENC.blif" );
323
324 strcpy( FileNameFin, pFunc->FileGeneric );
325 strcat( FileNameFin, "_LUT.blif" );
326
327 // derive the single-output function IN THE NEW MANAGER
328 clk1 = Abc_Clock();
329// aFunc = GetSingleOutputFunction( dd, pFunc->pOutputs, nOuts, pbVarsEnc, nVarsEnc ); Cudd_Ref( aFunc );
330 aFunc = GetSingleOutputFunctionRemappedNewDD( dd, pFunc->pOutputs, nOuts, &DdNew ); Cudd_Ref( aFunc );
331 printf( "Single-output function derivation time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
332// s_RemappingTime = Abc_Clock() - clk1;
333
334 // dispose of the multiple-output function
335 Extra_Dissolve( pFunc );
336
337 // reorder the single output function
338 printf( "\nReordering variables in the new manager...\n");
339 clk1 = Abc_Clock();
340 printf( "Node count before = %d\n", Cudd_DagSize( aFunc ) );
341// Cudd_ReduceHeap(DdNew, CUDD_REORDER_SIFT,1);
342 Cudd_ReduceHeap(DdNew, CUDD_REORDER_SYMM_SIFT,1);
343// Cudd_ReduceHeap(DdNew, CUDD_REORDER_SYMM_SIFT,1);
344 printf( "Node count after = %d\n", Cudd_DagSize( aFunc ) );
345 printf( "Variable reordering time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
346 printf( "\n" );
347
348//fprintf( pTable, "%d ", Cudd_DagSize( aFunc ) );
349//fprintf( pTable, "%d ", Extra_ProfileWidthMax(DdNew, aFunc) );
350
351
352 // create the names to be used with the new manager
353 nNames = DdNew->size;
354 for ( x = 0; x < nNames; x++ )
355 {
356 sprintf( Buffer, "v%02d", x );
357 pNames[x] = Extra_UtilStrsav( Buffer );
358 }
359
360
361
362 // write the single-output function into BLIF for verification
363 clk1 = Abc_Clock();
364 WriteSingleOutputFunctionBlif( DdNew, aFunc, pNames, nNames, FileNameIni );
365 printf( "Single-output function writing time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
366
367
369 // verification of single output function
370 clk1 = Abc_Clock();
371 {
372 BFunc g_Func;
373 DdNode * aRes;
374
375 g_Func.dd = DdNew;
376 g_Func.FileInput = Extra_UtilStrsav(FileNameIni);
377
378 if ( Extra_ReadFile( &g_Func ) == 0 )
379 {
380 printf( "\nSomething did not work out while reading the input file for verification\n");
381 Extra_Dissolve( &g_Func );
382 return;
383 }
384
385 aRes = Cudd_BddToAdd( DdNew, g_Func.pOutputs[0] ); Cudd_Ref( aRes );
386
387 if ( aRes != aFunc )
388 printf( "\nVerification FAILED!\n");
389 else
390 printf( "\nVerification okay!\n");
391
392 Cudd_RecursiveDeref( DdNew, aRes );
393
394 // delocate
395 Extra_Dissolve( &g_Func );
396 }
397 printf( "Preliminary verification time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
399
400
401 CreateDecomposedNetwork( DdNew, aFunc, pNames, nNames, FileNameFin, nLutSize, 0 );
402
403/*
405 // verification of the decomposed LUT network
406 clk1 = Abc_Clock();
407 {
408 BFunc g_Func;
409 DdNode * aRes;
410
411 g_Func.dd = DdNew;
412 g_Func.FileInput = Extra_UtilStrsav(FileNameFin);
413
414 if ( Extra_ReadFile( &g_Func ) == 0 )
415 {
416 printf( "\nSomething did not work out while reading the input file for verification\n");
417 Extra_Dissolve( &g_Func );
418 return;
419 }
420
421 aRes = Cudd_BddToAdd( DdNew, g_Func.pOutputs[0] ); Cudd_Ref( aRes );
422
423 if ( aRes != aFunc )
424 printf( "\nFinal verification FAILED!\n");
425 else
426 printf( "\nFinal verification okay!\n");
427
428 Cudd_RecursiveDeref( DdNew, aRes );
429
430 // delocate
431 Extra_Dissolve( &g_Func );
432 }
433 printf( "Final verification time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
435*/
436
437
438 Cudd_RecursiveDeref( DdNew, aFunc );
439
440 // release the names
441 for ( i = 0; i < nNames; i++ )
442 ABC_FREE( pNames[i] );
443
444
445
447 // check for remaining references in the package
448 RetValue = Cudd_CheckZeroRef( DdNew );
449 printf( "\nThe number of referenced nodes in the new manager = %d\n", RetValue );
450 Cudd_Quit( DdNew );
451
452//fprintf( pTable, "\n" );
453//fclose( pTable );
454
455}
456
457#endif
458
462
464static int s_SuppSize[MAXOUTPUTS];
465int CompareSupports( int *ptrX, int *ptrY )
466{
467 return ( s_SuppSize[*ptrY] - s_SuppSize[*ptrX] );
468}
469
470
471
473static int s_MintOnes[MAXOUTPUTS];
474int CompareMinterms( int *ptrX, int *ptrY )
475{
476 return ( s_MintOnes[*ptrY] - s_MintOnes[*ptrX] );
477}
478
479
480int GrayCode ( int BinCode )
481{
482 return BinCode ^ ( BinCode >> 1 );
483}
484
496DdNode * GetSingleOutputFunction( DdManager * dd, DdNode ** pbOuts, int nOuts, DdNode ** pbVarsEnc, int nVarsEnc, int fVerbose )
497{
498 int i;
499 DdNode * bResult, * aResult;
500 DdNode * bCube, * bTemp, * bProd;
501
502 int Order[MAXOUTPUTS];
503// int OrderMint[MAXOUTPUTS];
504
505 // sort the output according to their support size
506 for ( i = 0; i < nOuts; i++ )
507 {
508 s_SuppSize[i] = Cudd_SupportSize( dd, pbOuts[i] );
509// s_MintOnes[i] = BitCount8[i];
510 Order[i] = i;
511// OrderMint[i] = i;
512 }
513
514 // order the outputs
515 qsort( (void*)Order, (size_t)nOuts, sizeof(int), (int(*)(const void*, const void*)) CompareSupports );
516 // order the outputs
517// qsort( (void*)OrderMint, (size_t)nOuts, sizeof(int), (int(*)(const void*, const void*)) CompareMinterms );
518
519
520 bResult = b0; Cudd_Ref( bResult );
521 for ( i = 0; i < nOuts; i++ )
522 {
523// bCube = Cudd_bddBitsToCube( dd, OrderMint[i], nVarsEnc, pbVarsEnc ); Cudd_Ref( bCube );
524// bProd = Cudd_bddAnd( dd, bCube, pbOuts[Order[nOuts-1-i]] ); Cudd_Ref( bProd );
525 bCube = Extra_bddBitsToCube( dd, i, nVarsEnc, pbVarsEnc, 1 ); Cudd_Ref( bCube );
526 bProd = Cudd_bddAnd( dd, bCube, pbOuts[Order[i]] ); Cudd_Ref( bProd );
527 Cudd_RecursiveDeref( dd, bCube );
528
529 bResult = Cudd_bddOr( dd, bProd, bTemp = bResult ); Cudd_Ref( bResult );
530 Cudd_RecursiveDeref( dd, bTemp );
531 Cudd_RecursiveDeref( dd, bProd );
532 }
533
534 // convert to the ADD
535if ( fVerbose )
536printf( "Single BDD size = %6d nodes\n", Cudd_DagSize(bResult) );
537 aResult = Cudd_BddToAdd( dd, bResult ); Cudd_Ref( aResult );
538 Cudd_RecursiveDeref( dd, bResult );
539if ( fVerbose )
540printf( "MTBDD = %6d nodes\n", Cudd_DagSize(aResult) );
541 Cudd_Deref( aResult );
542 return aResult;
543}
544/*
545DdNode * GetSingleOutputFunction( DdManager * dd, DdNode ** pbOuts, int nOuts, DdNode ** pbVarsEnc, int nVarsEnc )
546{
547 int i;
548 DdNode * bResult, * aResult;
549 DdNode * bCube, * bTemp, * bProd;
550
551 bResult = b0; Cudd_Ref( bResult );
552 for ( i = 0; i < nOuts; i++ )
553 {
554// bCube = Extra_bddBitsToCube( dd, i, nVarsEnc, pbVarsEnc ); Cudd_Ref( bCube );
555 bCube = Extra_bddBitsToCube( dd, nOuts-1-i, nVarsEnc, pbVarsEnc ); Cudd_Ref( bCube );
556 bProd = Cudd_bddAnd( dd, bCube, pbOuts[i] ); Cudd_Ref( bProd );
557 Cudd_RecursiveDeref( dd, bCube );
558
559 bResult = Cudd_bddOr( dd, bProd, bTemp = bResult ); Cudd_Ref( bResult );
560 Cudd_RecursiveDeref( dd, bTemp );
561 Cudd_RecursiveDeref( dd, bProd );
562 }
563
564 // conver to the ADD
565 aResult = Cudd_BddToAdd( dd, bResult ); Cudd_Ref( aResult );
566 Cudd_RecursiveDeref( dd, bResult );
567
568 Cudd_Deref( aResult );
569 return aResult;
570}
571*/
572
573
577
578
590DdNode * GetSingleOutputFunctionRemapped( DdManager * dd, DdNode ** pOutputs, int nOuts, DdNode ** pbVarsEnc, int nVarsEnc )
591// returns the ADD of the remapped function
592{
593 static int Permute[MAXINPUTS];
594 static DdNode * pRemapped[MAXOUTPUTS];
595
596 DdNode * bSupp, * bTemp;
597 int i, Counter;
598 DdNode * bFunc;
599 DdNode * aFunc;
600
601 Cudd_AutodynDisable(dd);
602
603 // perform the remapping
604 for ( i = 0; i < nOuts; i++ )
605 {
606 // get support
607 bSupp = Cudd_Support( dd, pOutputs[i] ); Cudd_Ref( bSupp );
608
609 // create the variable map
610 Counter = 0;
611 for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
612 Permute[bTemp->index] = Counter++;
613
614 // transfer the BDD and remap it
615 pRemapped[i] = Cudd_bddPermute( dd, pOutputs[i], Permute ); Cudd_Ref( pRemapped[i] );
616
617 // remove support
618 Cudd_RecursiveDeref( dd, bSupp );
619 }
620
621 // perform the encoding
622 bFunc = Extra_bddEncodingBinary( dd, pRemapped, nOuts, pbVarsEnc, nVarsEnc ); Cudd_Ref( bFunc );
623
624 // convert to ADD
625 aFunc = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( aFunc );
626 Cudd_RecursiveDeref( dd, bFunc );
627
628 // deref the intermediate results
629 for ( i = 0; i < nOuts; i++ )
630 Cudd_RecursiveDeref( dd, pRemapped[i] );
631
632 Cudd_Deref( aFunc );
633 return aFunc;
634}
635
636
648DdNode * GetSingleOutputFunctionRemappedNewDD( DdManager * dd, DdNode ** pOutputs, int nOuts, DdManager ** DdNew )
649// returns the ADD of the remapped function
650{
651 static int Permute[MAXINPUTS];
652 static DdNode * pRemapped[MAXOUTPUTS];
653
654 static DdNode * pbVarsEnc[MAXINPUTS];
655 int nVarsEnc;
656
657 DdManager * ddnew;
658
659 DdNode * bSupp, * bTemp;
660 int i, v, Counter;
661 DdNode * bFunc;
662
663 // these are in the new manager
664 DdNode * bFuncNew;
665 DdNode * aFuncNew;
666
667 int nVarsMax = 0;
668
669 // perform the remapping and write the DDs into the new manager
670 for ( i = 0; i < nOuts; i++ )
671 {
672 // get support
673 bSupp = Cudd_Support( dd, pOutputs[i] ); Cudd_Ref( bSupp );
674
675 // create the variable map
676 // to remap the DD into the upper part of the manager
677 Counter = 0;
678 for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
679 Permute[bTemp->index] = dd->invperm[Counter++];
680
681 // transfer the BDD and remap it
682 pRemapped[i] = Cudd_bddPermute( dd, pOutputs[i], Permute ); Cudd_Ref( pRemapped[i] );
683
684 // remove support
685 Cudd_RecursiveDeref( dd, bSupp );
686
687
688 // determine the largest support size
689 if ( nVarsMax < Counter )
690 nVarsMax = Counter;
691 }
692
693 // select the encoding variables to follow immediately after the original variables
694 nVarsEnc = Abc_Base2Log(nOuts);
695/*
696 for ( v = 0; v < nVarsEnc; v++ )
697 if ( nVarsMax + v < dd->size )
698 pbVarsEnc[v] = dd->var[ dd->invperm[nVarsMax+v] ];
699 else
700 pbVarsEnc[v] = Cudd_bddNewVar( dd );
701*/
702 // create the new variables on top of the manager
703 for ( v = 0; v < nVarsEnc; v++ )
704 pbVarsEnc[v] = Cudd_bddNewVarAtLevel( dd, v );
705
706//fprintf( pTable, "%d ", Cudd_SharingSize( pRemapped, nOuts ) );
707//fprintf( pTable, "%d ", Extra_ProfileWidthSharingMax(dd, pRemapped, nOuts) );
708
709
710 // perform the encoding
711 bFunc = Extra_bddEncodingBinary( dd, pRemapped, nOuts, pbVarsEnc, nVarsEnc ); Cudd_Ref( bFunc );
712
713
714 // find the cross-manager permutation
715 // the variable from the level v in the old manager
716 // should become a variable number v in the new manager
717 for ( v = 0; v < nVarsMax + nVarsEnc; v++ )
718 Permute[dd->invperm[v]] = v;
719
720
722 // start the new manager
723 ddnew = Cudd_Init( nVarsMax + nVarsEnc, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
724// Cudd_AutodynDisable(ddnew);
725 Cudd_AutodynEnable(dd, CUDD_REORDER_SYMM_SIFT);
726
727 // transfer it to the new manager
728 bFuncNew = Cudd_bddTransferPermute( dd, ddnew, bFunc, Permute ); Cudd_Ref( bFuncNew );
730
731
732 // deref the intermediate results in the old manager
733 Cudd_RecursiveDeref( dd, bFunc );
734 for ( i = 0; i < nOuts; i++ )
735 Cudd_RecursiveDeref( dd, pRemapped[i] );
736
737
739 // convert to ADD in the new manager
740 aFuncNew = Cudd_BddToAdd( ddnew, bFuncNew ); Cudd_Ref( aFuncNew );
741 Cudd_RecursiveDeref( ddnew, bFuncNew );
742
743 // return the manager
744 *DdNew = ddnew;
746
747 Cudd_Deref( aFuncNew );
748 return aFuncNew;
749}
750
754
755void WriteDDintoBLIFfile( FILE * pFile, DdNode * Func, char * OutputName, char * Prefix, char ** InputNames );
756
757
769void WriteSingleOutputFunctionBlif( DdManager * dd, DdNode * aFunc, char ** pNames, int nNames, char * FileName )
770{
771 int i;
772 FILE * pFile;
773
774 // start the file
775 pFile = fopen( FileName, "w" );
776 fprintf( pFile, ".model %s\n", FileName );
777
778 fprintf( pFile, ".inputs" );
779 for ( i = 0; i < nNames; i++ )
780 fprintf( pFile, " %s", pNames[i] );
781 fprintf( pFile, "\n" );
782 fprintf( pFile, ".outputs F" );
783 fprintf( pFile, "\n" );
784
785 // write the DD into the file
786 WriteDDintoBLIFfile( pFile, aFunc, "F", "", pNames );
787
788 fprintf( pFile, ".end\n" );
789 fclose( pFile );
790}
791
803void WriteDDintoBLIFfile( FILE * pFile, DdNode * Func, char * OutputName, char * Prefix, char ** InputNames )
804// writes the main part of the BLIF file
805// Func is a BDD or a 0-1 ADD to be written
806// OutputName is the name of the output
807// Prefix is attached to each intermendiate signal to make it unique
808// InputNames are the names of the input signals
809// (some part of the code is borrowed from Cudd_DumpDot())
810{
811 int i;
812 st__table * visited;
813 st__generator * gen = NULL;
814 long refAddr, diff, mask;
815 DdNode * Node, * Else, * ElseR, * Then;
816
817 /* Initialize symbol table for visited nodes. */
819
820 /* Collect all the nodes of this DD in the symbol table. */
821 cuddCollectNodes( Cudd_Regular(Func), visited );
822
823 /* Find how many most significant hex digits are identical
824 ** in the addresses of all the nodes. Build a mask based
825 ** on this knowledge, so that digits that carry no information
826 ** will not be printed. This is done in two steps.
827 ** 1. We scan the symbol table to find the bits that differ
828 ** in at least 2 addresses.
829 ** 2. We choose one of the possible masks. There are 8 possible
830 ** masks for 32-bit integer, and 16 possible masks for 64-bit
831 ** integers.
832 */
833
834 /* Find the bits that are different. */
835 refAddr = ( long )Cudd_Regular(Func);
836 diff = 0;
837 gen = st__init_gen( visited );
838 while ( st__gen( gen, ( const char ** ) &Node, NULL ) )
839 {
840 diff |= refAddr ^ ( long ) Node;
841 }
842 st__free_gen( gen );
843 gen = NULL;
844
845 /* Choose the mask. */
846 for ( i = 0; ( unsigned ) i < 8 * sizeof( long ); i += 4 )
847 {
848 mask = ( 1 << i ) - 1;
849 if ( diff <= mask )
850 break;
851 }
852
853
854 // write the buffer for the output
855 fprintf( pFile, ".names %s%lx %s\n", Prefix, ( mask & (long)Cudd_Regular(Func) ) / sizeof(DdNode), OutputName );
856 fprintf( pFile, "%s 1\n", (Cudd_IsComplement(Func))? "0": "1" );
857
858
859 gen = st__init_gen( visited );
860 while ( st__gen( gen, ( const char ** ) &Node, NULL ) )
861 {
862 if ( Node->index == CUDD_MAXINDEX )
863 {
864 // write the terminal node
865 fprintf( pFile, ".names %s%lx\n", Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
866 fprintf( pFile, " %s\n", (cuddV(Node) == 0.0)? "0": "1" );
867 continue;
868 }
869
870 Else = cuddE(Node);
871 ElseR = Cudd_Regular(Else);
872 Then = cuddT(Node);
873
874 assert( InputNames[Node->index] );
875 if ( Else == ElseR )
876 { // no inverter
877 fprintf( pFile, ".names %s %s%lx %s%lx %s%lx\n", InputNames[Node->index],
878 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
879 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
880 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
881 fprintf( pFile, "01- 1\n" );
882 fprintf( pFile, "1-1 1\n" );
883 }
884 else
885 { // inverter
886 int * pSlot;
887 fprintf( pFile, ".names %s %s%lx_i %s%lx %s%lx\n", InputNames[Node->index],
888 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
889 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
890 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
891 fprintf( pFile, "01- 1\n" );
892 fprintf( pFile, "1-1 1\n" );
893
894 // if the inverter is written, skip
895 if ( ! st__find( visited, (char *)ElseR, (char ***)&pSlot ) )
896 assert( 0 );
897 if ( *pSlot )
898 continue;
899 *pSlot = 1;
900
901 fprintf( pFile, ".names %s%lx %s%lx_i\n",
902 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
903 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode) );
904 fprintf( pFile, "0 1\n" );
905 }
906 }
907 st__free_gen( gen );
908 gen = NULL;
909 st__free_table( visited );
910}
911
912
913
914
915static DdManager * s_ddmin;
916
928void WriteDDintoBLIFfileReorder( DdManager * dd, FILE * pFile, DdNode * Func, char * OutputName, char * Prefix, char ** InputNames )
929// writes the main part of the BLIF file
930// Func is a BDD or a 0-1 ADD to be written
931// OutputName is the name of the output
932// Prefix is attached to each intermendiate signal to make it unique
933// InputNames are the names of the input signals
934// (some part of the code is borrowed from Cudd_DumpDot())
935{
936 int i;
937 st__table * visited;
938 st__generator * gen = NULL;
939 long refAddr, diff, mask;
940 DdNode * Node, * Else, * ElseR, * Then;
941
942
944 DdNode * bFmin;
945 abctime clk1;
946
947 if ( s_ddmin == NULL )
948 s_ddmin = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
949
950 clk1 = Abc_Clock();
951 bFmin = Cudd_bddTransfer( dd, s_ddmin, Func ); Cudd_Ref( bFmin );
952
953 // reorder
954 printf( "Nodes before = %d. ", Cudd_DagSize(bFmin) );
955 Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SYMM_SIFT,1);
956// Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SYMM_SIFT_CONV,1);
957 printf( "Nodes after = %d. \n", Cudd_DagSize(bFmin) );
959
960
961
962 /* Initialize symbol table for visited nodes. */
964
965 /* Collect all the nodes of this DD in the symbol table. */
966 cuddCollectNodes( Cudd_Regular(bFmin), visited );
967
968 /* Find how many most significant hex digits are identical
969 ** in the addresses of all the nodes. Build a mask based
970 ** on this knowledge, so that digits that carry no information
971 ** will not be printed. This is done in two steps.
972 ** 1. We scan the symbol table to find the bits that differ
973 ** in at least 2 addresses.
974 ** 2. We choose one of the possible masks. There are 8 possible
975 ** masks for 32-bit integer, and 16 possible masks for 64-bit
976 ** integers.
977 */
978
979 /* Find the bits that are different. */
980 refAddr = ( long )Cudd_Regular(bFmin);
981 diff = 0;
982 gen = st__init_gen( visited );
983 while ( st__gen( gen, ( const char ** ) &Node, NULL ) )
984 {
985 diff |= refAddr ^ ( long ) Node;
986 }
987 st__free_gen( gen );
988 gen = NULL;
989
990 /* Choose the mask. */
991 for ( i = 0; ( unsigned ) i < 8 * sizeof( long ); i += 4 )
992 {
993 mask = ( 1 << i ) - 1;
994 if ( diff <= mask )
995 break;
996 }
997
998
999 // write the buffer for the output
1000 fprintf( pFile, ".names %s%lx %s\n", Prefix, ( mask & (long)Cudd_Regular(bFmin) ) / sizeof(DdNode), OutputName );
1001 fprintf( pFile, "%s 1\n", (Cudd_IsComplement(bFmin))? "0": "1" );
1002
1003
1004 gen = st__init_gen( visited );
1005 while ( st__gen( gen, ( const char ** ) &Node, NULL ) )
1006 {
1007 if ( Node->index == CUDD_MAXINDEX )
1008 {
1009 // write the terminal node
1010 fprintf( pFile, ".names %s%lx\n", Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
1011 fprintf( pFile, " %s\n", (cuddV(Node) == 0.0)? "0": "1" );
1012 continue;
1013 }
1014
1015 Else = cuddE(Node);
1016 ElseR = Cudd_Regular(Else);
1017 Then = cuddT(Node);
1018
1019 assert( InputNames[Node->index] );
1020 if ( Else == ElseR )
1021 { // no inverter
1022 fprintf( pFile, ".names %s %s%lx %s%lx %s%lx\n", InputNames[Node->index],
1023 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
1024 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
1025 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
1026 fprintf( pFile, "01- 1\n" );
1027 fprintf( pFile, "1-1 1\n" );
1028 }
1029 else
1030 { // inverter
1031 fprintf( pFile, ".names %s %s%lx_i %s%lx %s%lx\n", InputNames[Node->index],
1032 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
1033 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
1034 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
1035 fprintf( pFile, "01- 1\n" );
1036 fprintf( pFile, "1-1 1\n" );
1037
1038 fprintf( pFile, ".names %s%lx %s%lx_i\n",
1039 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
1040 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode) );
1041 fprintf( pFile, "0 1\n" );
1042 }
1043 }
1044 st__free_gen( gen );
1045 gen = NULL;
1046 st__free_table( visited );
1047
1048
1050 Cudd_RecursiveDeref( s_ddmin, bFmin );
1052}
1053
1054
1055
1056
1060static DdNode * cuddBddTransferPermuteRecur
1061ARGS((DdManager * ddS, DdManager * ddD, DdNode * f, st__table * table, int * Permute ));
1062
1063static DdNode * cuddBddTransferPermute
1064ARGS((DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute));
1065
1081DdNode *
1082Cudd_bddTransferPermute( DdManager * ddSource,
1083 DdManager * ddDestination, DdNode * f, int * Permute )
1084{
1085 DdNode *res;
1086 do
1087 {
1088 ddDestination->reordered = 0;
1089 res = cuddBddTransferPermute( ddSource, ddDestination, f, Permute );
1090 }
1091 while ( ddDestination->reordered == 1 );
1092 return ( res );
1093
1094} /* end of Cudd_bddTransferPermute */
1095
1096
1097/*---------------------------------------------------------------------------*/
1098/* Definition of internal functions */
1099/*---------------------------------------------------------------------------*/
1100
1101
1115DdNode *
1116cuddBddTransferPermute( DdManager * ddS, DdManager * ddD, DdNode * f, int * Permute )
1117{
1118 DdNode *res;
1119 st__table *table = NULL;
1120 st__generator *gen = NULL;
1121 DdNode *key, *value;
1122
1124 if ( table == NULL )
1125 goto failure;
1126 res = cuddBddTransferPermuteRecur( ddS, ddD, f, table, Permute );
1127 if ( res != NULL )
1128 cuddRef( res );
1129
1130 /* Dereference all elements in the table and dispose of the table.
1131 ** This must be done also if res is NULL to avoid leaks in case of
1132 ** reordering. */
1133 gen = st__init_gen( table );
1134 if ( gen == NULL )
1135 goto failure;
1136 while ( st__gen( gen, ( const char ** ) &key, ( char ** ) &value ) )
1137 {
1138 Cudd_RecursiveDeref( ddD, value );
1139 }
1140 st__free_gen( gen );
1141 gen = NULL;
1142 st__free_table( table );
1143 table = NULL;
1144
1145 if ( res != NULL )
1146 cuddDeref( res );
1147 return ( res );
1148
1149 failure:
1150 if ( table != NULL )
1151 st__free_table( table );
1152 if ( gen != NULL )
1153 st__free_gen( gen );
1154 return ( NULL );
1155
1156} /* end of cuddBddTransferPermute */
1157
1158
1171static DdNode *
1172cuddBddTransferPermuteRecur( DdManager * ddS,
1173 DdManager * ddD, DdNode * f, st__table * table, int * Permute )
1174{
1175 DdNode *ft, *fe, *t, *e, *var, *res;
1176 DdNode *one, *zero;
1177 int index;
1178 int comple = 0;
1179
1180 statLine( ddD );
1181 one = DD_ONE( ddD );
1182 comple = Cudd_IsComplement( f );
1183
1184 /* Trivial cases. */
1185 if ( Cudd_IsConstant( f ) )
1186 return ( Cudd_NotCond( one, comple ) );
1187
1188 /* Make canonical to increase the utilization of the cache. */
1189 f = Cudd_NotCond( f, comple );
1190 /* Now f is a regular pointer to a non-constant node. */
1191
1192 /* Check the cache. */
1193 if ( st__lookup( table, ( char * ) f, ( char ** ) &res ) )
1194 return ( Cudd_NotCond( res, comple ) );
1195
1196 /* Recursive step. */
1197 index = Permute[f->index];
1198 ft = cuddT( f );
1199 fe = cuddE( f );
1200
1201 t = cuddBddTransferPermuteRecur( ddS, ddD, ft, table, Permute );
1202 if ( t == NULL )
1203 {
1204 return ( NULL );
1205 }
1206 cuddRef( t );
1207
1208 e = cuddBddTransferPermuteRecur( ddS, ddD, fe, table, Permute );
1209 if ( e == NULL )
1210 {
1211 Cudd_RecursiveDeref( ddD, t );
1212 return ( NULL );
1213 }
1214 cuddRef( e );
1215
1216 zero = Cudd_Not( one );
1217 var = cuddUniqueInter( ddD, index, one, zero );
1218 if ( var == NULL )
1219 {
1220 Cudd_RecursiveDeref( ddD, t );
1221 Cudd_RecursiveDeref( ddD, e );
1222 return ( NULL );
1223 }
1224 res = cuddBddIteRecur( ddD, var, t, e );
1225 if ( res == NULL )
1226 {
1227 Cudd_RecursiveDeref( ddD, t );
1228 Cudd_RecursiveDeref( ddD, e );
1229 return ( NULL );
1230 }
1231 cuddRef( res );
1232 Cudd_RecursiveDeref( ddD, t );
1233 Cudd_RecursiveDeref( ddD, e );
1234
1235 if ( st__add_direct( table, ( char * ) f, ( char * ) res ) ==
1237 {
1238 Cudd_RecursiveDeref( ddD, res );
1239 return ( NULL );
1240 }
1241 return ( Cudd_NotCond( res, comple ) );
1242
1243} /* end of cuddBddTransferPermuteRecur */
1244
1248
1249
1250
1251
1253
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
ABC_DLL Abc_Frame_t * Abc_FrameGetGlobalFrame()
Definition mainFrame.c:643
#define ARGS(protos)
Definition avl.h:20
#define b0
Definition bbrImage.c:96
ABC_NAMESPACE_IMPL_START typedef signed char value
DdNode * GetSingleOutputFunctionRemapped(DdManager *dd, DdNode **pOutputs, int nOuts, DdNode **pbVarsEnc, int nVarsEnc)
INPUT REMAPPING ///.
Definition casCore.c:590
ABC_NAMESPACE_IMPL_START DdNode * GetSingleOutputFunction(DdManager *dd, DdNode **pbOuts, int nOuts, DdNode **pbVarsEnc, int nVarsEnc, int fVerbose)
static functions ///
Definition casCore.c:496
DdNode * Cudd_bddTransferPermute(DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
Definition casCore.c:1082
int Abc_CascadeExperiment(char *pFileGeneric, DdManager *dd, DdNode **pOutputs, int nInputs, int nOutputs, int nLutSize, int fCheck, int fVerbose)
EXTERNAL FUNCTIONS ///.
Definition casCore.c:79
int CreateDecomposedNetwork(DdManager *dd, DdNode *aFunc, char **pNames, int nNames, char *FileName, int nLutSize, int fCheck, int fVerbose)
EXTERNAL FUNCTIONS ///.
Definition casDec.c:108
void WriteSingleOutputFunctionBlif(DdManager *dd, DdNode *aFunc, char **pNames, int nNames, char *FileName)
Definition casCore.c:769
int CompareSupports(int *ptrX, int *ptrY)
Definition casCore.c:465
void WriteDDintoBLIFfile(FILE *pFile, DdNode *Func, char *OutputName, char *Prefix, char **InputNames)
BLIF WRITING FUNCTIONS ///.
Definition casCore.c:803
void WriteDDintoBLIFfileReorder(DdManager *dd, FILE *pFile, DdNode *Func, char *OutputName, char *Prefix, char **InputNames)
Definition casCore.c:928
int GrayCode(int BinCode)
Definition casCore.c:480
DdNode * GetSingleOutputFunctionRemappedNewDD(DdManager *dd, DdNode **pOutputs, int nOuts, DdManager **DdNew)
Definition casCore.c:648
int CompareMinterms(int *ptrX, int *ptrY)
Definition casCore.c:474
DdNode * cuddBddTransferPermute(DdManager *ddS, DdManager *ddD, DdNode *f, int *Permute)
Definition casCore.c:1116
#define MAXINPUTS
INCLUDES ///.
Definition cas.h:38
#define MAXOUTPUTS
Definition cas.h:39
ABC_DLL int Cmd_CommandExecute(Abc_Frame_t *pAbc, const char *sCommand)
Definition cmdApi.c:193
DdNode * Extra_bddBitsToCube(DdManager *dd, int Code, int CodeWidth, DdNode **pbVars, int fMsbFirst)
DdNode * Extra_bddEncodingBinary(DdManager *dd, DdNode **pbFuncs, int nFuncs, DdNode **pbVars, int nVars)
char * Extra_UtilStrsav(const char *s)
enum keys key
Definition main.h:25
unsigned short var
Definition giaNewBdd.h:35
int st__gen(st__generator *gen, const char **key_p, char **value_p)
Definition st.c:501
int st__ptrhash(const char *, int)
Definition st.c:467
int st__ptrcmp(const char *, const char *)
Definition st.c:479
void st__free_gen(st__generator *gen)
Definition st.c:555
int st__find(st__table *table, char *key, char ***slot)
Definition st.c:264
int st__lookup(st__table *table, const char *key, char **value)
Definition st.c:114
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition st.c:72
st__generator * st__init_gen(st__table *table)
Definition st.c:485
int st__add_direct(st__table *table, char *key, char *value)
Definition st.c:205
void st__free_table(st__table *table)
Definition st.c:81
#define st__OUT_OF_MEM
Definition st.h:113
Definition st.h:52
#define assert(ex)
Definition util_old.h:213
char * sprintf()
char * strcpy()
char * strcat()