37DdNode *
GetSingleOutputFunction( DdManager * dd, DdNode ** pbOuts,
int nOuts, DdNode ** pbVarsEnc,
int nVarsEnc,
int fVerbose );
41extern int CreateDecomposedNetwork( DdManager * dd, DdNode * aFunc,
char ** pNames,
int nNames,
char * FileName,
int nLutSize,
int fCheck,
int fVerbose );
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" )
79int Abc_CascadeExperiment(
char * pFileGeneric, DdManager * dd, DdNode ** pOutputs,
int nInputs,
int nOutputs,
int nLutSize,
int fCheck,
int fVerbose )
94 char FileNameIni[100];
95 char FileNameFin[100];
106 strcpy( FileNameIni, pFileGeneric );
107 strcat( FileNameIni,
"_ENC.blif" );
109 strcpy( FileNameFin, pFileGeneric );
110 strcat( FileNameFin,
"_LUT.blif" );
114 nVarsEnc = Abc_Base2Log( nOuts );
115 for ( i = 0; i < nVarsEnc; i++ )
116 pbVarsEnc[i] = Cudd_bddNewVarAtLevel( dd, i );
120 nNames = nVars + nVarsEnc;
121 for ( i = 0; i < nVars; i++ )
124 sprintf( Buffer,
"pi%03d", i );
128 for ( ; i < nNames; i++ )
130 sprintf( Buffer,
"OutEnc_%02d", i-nVars );
162 Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1);
163 Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1);
169 printf(
"MTBDD reordered = %6d nodes\n", Cudd_DagSize( aFunc ) );
171 printf(
"Variable reordering time = %.2f sec\n", (
float)(Abc_Clock() - clk1)/(
float)(CLOCKS_PER_SEC) );
189 // verification of single output function
196 g_Func.FileInput = Extra_UtilStrsav(FileNameIni);
198 if ( Extra_ReadFile( &g_Func ) == 0 )
200 printf( "\nSomething did not work out while reading the input file for verification\n");
201 Extra_Dissolve( &g_Func );
205 aRes = Cudd_BddToAdd( dd, g_Func.pOutputs[0] ); Cudd_Ref( aRes );
208 printf( "\nVerification FAILED!\n");
210 printf( "\nVerification okay!\n");
212 Cudd_RecursiveDeref( dd, aRes );
215 Extra_Dissolve( &g_Func );
217 printf( "Preliminary verification time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
226 // verification of the decomposed LUT network
233 g_Func.FileInput = Extra_UtilStrsav(FileNameFin);
235 if ( Extra_ReadFile( &g_Func ) == 0 )
237 printf( "\nSomething did not work out while reading the input file for verification\n");
238 Extra_Dissolve( &g_Func );
242 aRes = Cudd_BddToAdd( dd, g_Func.pOutputs[0] ); Cudd_Ref( aRes );
245 printf( "\nFinal verification FAILED!\n");
247 printf( "\nFinal verification okay!\n");
249 Cudd_RecursiveDeref( dd, aRes );
252 Extra_Dissolve( &g_Func );
254 printf( "Final verification time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
262 sprintf( Command,
"cec %s %s", FileNameIni, FileNameFin );
266 Cudd_RecursiveDeref( dd, aFunc );
269 for ( i = 0; i < nNames; i++ )
292void Experiment2( BFunc * pFunc )
295 int nVars = pFunc->nInputs;
296 int nOuts = pFunc->nOutputs;
297 DdManager * dd = pFunc->dd;
308 char FileNameIni[100];
309 char FileNameFin[100];
321 strcpy( FileNameIni, pFunc->FileGeneric );
322 strcat( FileNameIni,
"_ENC.blif" );
324 strcpy( FileNameFin, pFunc->FileGeneric );
325 strcat( FileNameFin,
"_LUT.blif" );
331 printf(
"Single-output function derivation time = %.2f sec\n", (
float)(Abc_Clock() - clk1)/(
float)(CLOCKS_PER_SEC) );
335 Extra_Dissolve( pFunc );
338 printf(
"\nReordering variables in the new manager...\n");
340 printf(
"Node count before = %d\n", Cudd_DagSize( aFunc ) );
342 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) );
353 nNames = DdNew->size;
354 for ( x = 0; x < nNames; x++ )
365 printf(
"Single-output function writing time = %.2f sec\n", (
float)(Abc_Clock() - clk1)/(
float)(CLOCKS_PER_SEC) );
378 if ( Extra_ReadFile( &g_Func ) == 0 )
380 printf(
"\nSomething did not work out while reading the input file for verification\n");
381 Extra_Dissolve( &g_Func );
385 aRes = Cudd_BddToAdd( DdNew, g_Func.pOutputs[0] ); Cudd_Ref( aRes );
388 printf(
"\nVerification FAILED!\n");
390 printf(
"\nVerification okay!\n");
392 Cudd_RecursiveDeref( DdNew, aRes );
395 Extra_Dissolve( &g_Func );
397 printf(
"Preliminary verification time = %.2f sec\n", (
float)(Abc_Clock() - clk1)/(
float)(CLOCKS_PER_SEC) );
405 // verification of the decomposed LUT network
412 g_Func.FileInput = Extra_UtilStrsav(FileNameFin);
414 if ( Extra_ReadFile( &g_Func ) == 0 )
416 printf( "\nSomething did not work out while reading the input file for verification\n");
417 Extra_Dissolve( &g_Func );
421 aRes = Cudd_BddToAdd( DdNew, g_Func.pOutputs[0] ); Cudd_Ref( aRes );
424 printf( "\nFinal verification FAILED!\n");
426 printf( "\nFinal verification okay!\n");
428 Cudd_RecursiveDeref( DdNew, aRes );
431 Extra_Dissolve( &g_Func );
433 printf( "Final verification time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
438 Cudd_RecursiveDeref( DdNew, aFunc );
441 for ( i = 0; i < nNames; i++ )
448 RetValue = Cudd_CheckZeroRef( DdNew );
449 printf(
"\nThe number of referenced nodes in the new manager = %d\n", RetValue );
467 return ( s_SuppSize[*ptrY] - s_SuppSize[*ptrX] );
476 return ( s_MintOnes[*ptrY] - s_MintOnes[*ptrX] );
482 return BinCode ^ ( BinCode >> 1 );
496DdNode *
GetSingleOutputFunction( DdManager * dd, DdNode ** pbOuts,
int nOuts, DdNode ** pbVarsEnc,
int nVarsEnc,
int fVerbose )
499 DdNode * bResult, * aResult;
500 DdNode * bCube, * bTemp, * bProd;
506 for ( i = 0; i < nOuts; i++ )
508 s_SuppSize[i] = Cudd_SupportSize( dd, pbOuts[i] );
515 qsort( (
void*)Order, (
size_t)nOuts,
sizeof(
int), (
int(*)(
const void*,
const void*))
CompareSupports );
520 bResult =
b0; Cudd_Ref( bResult );
521 for ( i = 0; i < nOuts; i++ )
526 bProd = Cudd_bddAnd( dd, bCube, pbOuts[Order[i]] ); Cudd_Ref( bProd );
527 Cudd_RecursiveDeref( dd, bCube );
529 bResult = Cudd_bddOr( dd, bProd, bTemp = bResult ); Cudd_Ref( bResult );
530 Cudd_RecursiveDeref( dd, bTemp );
531 Cudd_RecursiveDeref( dd, bProd );
536printf(
"Single BDD size = %6d nodes\n", Cudd_DagSize(bResult) );
537 aResult = Cudd_BddToAdd( dd, bResult ); Cudd_Ref( aResult );
538 Cudd_RecursiveDeref( dd, bResult );
540printf(
"MTBDD = %6d nodes\n", Cudd_DagSize(aResult) );
541 Cudd_Deref( aResult );
596 DdNode * bSupp, * bTemp;
601 Cudd_AutodynDisable(dd);
604 for ( i = 0; i < nOuts; i++ )
607 bSupp = Cudd_Support( dd, pOutputs[i] ); Cudd_Ref( bSupp );
611 for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
612 Permute[bTemp->index] = Counter++;
615 pRemapped[i] = Cudd_bddPermute( dd, pOutputs[i], Permute ); Cudd_Ref( pRemapped[i] );
618 Cudd_RecursiveDeref( dd, bSupp );
625 aFunc = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( aFunc );
626 Cudd_RecursiveDeref( dd, bFunc );
629 for ( i = 0; i < nOuts; i++ )
630 Cudd_RecursiveDeref( dd, pRemapped[i] );
659 DdNode * bSupp, * bTemp;
670 for ( i = 0; i < nOuts; i++ )
673 bSupp = Cudd_Support( dd, pOutputs[i] ); Cudd_Ref( bSupp );
678 for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) )
679 Permute[bTemp->index] = dd->invperm[Counter++];
682 pRemapped[i] = Cudd_bddPermute( dd, pOutputs[i], Permute ); Cudd_Ref( pRemapped[i] );
685 Cudd_RecursiveDeref( dd, bSupp );
689 if ( nVarsMax < Counter )
694 nVarsEnc = Abc_Base2Log(nOuts);
703 for ( v = 0; v < nVarsEnc; v++ )
704 pbVarsEnc[v] = Cudd_bddNewVarAtLevel( dd, v );
717 for ( v = 0; v < nVarsMax + nVarsEnc; v++ )
718 Permute[dd->invperm[v]] = v;
723 ddnew = Cudd_Init( nVarsMax + nVarsEnc, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
725 Cudd_AutodynEnable(dd, CUDD_REORDER_SYMM_SIFT);
733 Cudd_RecursiveDeref( dd, bFunc );
734 for ( i = 0; i < nOuts; i++ )
735 Cudd_RecursiveDeref( dd, pRemapped[i] );
740 aFuncNew = Cudd_BddToAdd( ddnew, bFuncNew ); Cudd_Ref( aFuncNew );
741 Cudd_RecursiveDeref( ddnew, bFuncNew );
747 Cudd_Deref( aFuncNew );
755void WriteDDintoBLIFfile( FILE * pFile, DdNode * Func,
char * OutputName,
char * Prefix,
char ** InputNames );
775 pFile = fopen( FileName,
"w" );
776 fprintf( pFile,
".model %s\n", FileName );
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" );
788 fprintf( pFile,
".end\n" );
803void WriteDDintoBLIFfile( FILE * pFile, DdNode * Func,
char * OutputName,
char * Prefix,
char ** InputNames )
814 long refAddr, diff, mask;
815 DdNode * Node, * Else, * ElseR, * Then;
821 cuddCollectNodes( Cudd_Regular(Func), visited );
835 refAddr = ( long )Cudd_Regular(Func);
838 while (
st__gen( gen, (
const char ** ) &Node, NULL ) )
840 diff |= refAddr ^ ( long ) Node;
846 for ( i = 0; ( unsigned ) i < 8 *
sizeof( long ); i += 4 )
848 mask = ( 1 << i ) - 1;
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" );
860 while (
st__gen( gen, (
const char ** ) &Node, NULL ) )
862 if ( Node->index == CUDD_MAXINDEX )
865 fprintf( pFile,
".names %s%lx\n", Prefix, ( mask & (
long)Node ) /
sizeof(DdNode) );
866 fprintf( pFile,
" %s\n", (cuddV(Node) == 0.0)?
"0":
"1" );
871 ElseR = Cudd_Regular(Else);
874 assert( InputNames[Node->index] );
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" );
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" );
895 if ( !
st__find( visited, (
char *)ElseR, (
char ***)&pSlot ) )
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" );
915static DdManager * s_ddmin;
939 long refAddr, diff, mask;
940 DdNode * Node, * Else, * ElseR, * Then;
947 if ( s_ddmin == NULL )
948 s_ddmin = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
951 bFmin = Cudd_bddTransfer( dd, s_ddmin, Func ); Cudd_Ref( bFmin );
954 printf(
"Nodes before = %d. ", Cudd_DagSize(bFmin) );
955 Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SYMM_SIFT,1);
957 printf(
"Nodes after = %d. \n", Cudd_DagSize(bFmin) );
966 cuddCollectNodes( Cudd_Regular(bFmin), visited );
980 refAddr = ( long )Cudd_Regular(bFmin);
983 while (
st__gen( gen, (
const char ** ) &Node, NULL ) )
985 diff |= refAddr ^ ( long ) Node;
991 for ( i = 0; ( unsigned ) i < 8 *
sizeof( long ); i += 4 )
993 mask = ( 1 << i ) - 1;
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" );
1005 while (
st__gen( gen, (
const char ** ) &Node, NULL ) )
1007 if ( Node->index == CUDD_MAXINDEX )
1010 fprintf( pFile,
".names %s%lx\n", Prefix, ( mask & (
long)Node ) /
sizeof(DdNode) );
1011 fprintf( pFile,
" %s\n", (cuddV(Node) == 0.0)?
"0":
"1" );
1016 ElseR = Cudd_Regular(Else);
1019 assert( InputNames[Node->index] );
1020 if ( Else == ElseR )
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" );
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" );
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" );
1050 Cudd_RecursiveDeref( s_ddmin, bFmin );
1060static DdNode * cuddBddTransferPermuteRecur
1061ARGS((DdManager * ddS, DdManager * ddD, DdNode * f,
st__table * table,
int * Permute ));
1064ARGS((DdManager * ddS, DdManager * ddD, DdNode * f,
int * Permute));
1083 DdManager * ddDestination, DdNode * f,
int * Permute )
1088 ddDestination->reordered = 0;
1091 while ( ddDestination->reordered == 1 );
1124 if ( table == NULL )
1126 res = cuddBddTransferPermuteRecur( ddS, ddD, f, table, Permute );
1138 Cudd_RecursiveDeref( ddD,
value );
1150 if ( table != NULL )
1172cuddBddTransferPermuteRecur( DdManager * ddS,
1173 DdManager * ddD, DdNode * f,
st__table * table,
int * Permute )
1175 DdNode *ft, *fe, *t, *e, *
var, *res;
1181 one = DD_ONE( ddD );
1182 comple = Cudd_IsComplement( f );
1185 if ( Cudd_IsConstant( f ) )
1186 return ( Cudd_NotCond( one, comple ) );
1189 f = Cudd_NotCond( f, comple );
1193 if (
st__lookup( table, (
char * ) f, (
char ** ) &res ) )
1194 return ( Cudd_NotCond( res, comple ) );
1197 index = Permute[f->index];
1201 t = cuddBddTransferPermuteRecur( ddS, ddD, ft, table, Permute );
1208 e = cuddBddTransferPermuteRecur( ddS, ddD, fe, table, Permute );
1211 Cudd_RecursiveDeref( ddD, t );
1216 zero = Cudd_Not( one );
1217 var = cuddUniqueInter( ddD, index, one, zero );
1220 Cudd_RecursiveDeref( ddD, t );
1221 Cudd_RecursiveDeref( ddD, e );
1224 res = cuddBddIteRecur( ddD, var, t, e );
1227 Cudd_RecursiveDeref( ddD, t );
1228 Cudd_RecursiveDeref( ddD, e );
1232 Cudd_RecursiveDeref( ddD, t );
1233 Cudd_RecursiveDeref( ddD, e );
1238 Cudd_RecursiveDeref( ddD, res );
1241 return ( Cudd_NotCond( res, comple ) );
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
ABC_DLL Abc_Frame_t * Abc_FrameGetGlobalFrame()
ABC_NAMESPACE_IMPL_START typedef signed char value
DdNode * GetSingleOutputFunctionRemapped(DdManager *dd, DdNode **pOutputs, int nOuts, DdNode **pbVarsEnc, int nVarsEnc)
INPUT REMAPPING ///.
ABC_NAMESPACE_IMPL_START DdNode * GetSingleOutputFunction(DdManager *dd, DdNode **pbOuts, int nOuts, DdNode **pbVarsEnc, int nVarsEnc, int fVerbose)
static functions ///
DdNode * Cudd_bddTransferPermute(DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
int Abc_CascadeExperiment(char *pFileGeneric, DdManager *dd, DdNode **pOutputs, int nInputs, int nOutputs, int nLutSize, int fCheck, int fVerbose)
EXTERNAL FUNCTIONS ///.
int CreateDecomposedNetwork(DdManager *dd, DdNode *aFunc, char **pNames, int nNames, char *FileName, int nLutSize, int fCheck, int fVerbose)
EXTERNAL FUNCTIONS ///.
void WriteSingleOutputFunctionBlif(DdManager *dd, DdNode *aFunc, char **pNames, int nNames, char *FileName)
int CompareSupports(int *ptrX, int *ptrY)
void WriteDDintoBLIFfile(FILE *pFile, DdNode *Func, char *OutputName, char *Prefix, char **InputNames)
BLIF WRITING FUNCTIONS ///.
void WriteDDintoBLIFfileReorder(DdManager *dd, FILE *pFile, DdNode *Func, char *OutputName, char *Prefix, char **InputNames)
int GrayCode(int BinCode)
DdNode * GetSingleOutputFunctionRemappedNewDD(DdManager *dd, DdNode **pOutputs, int nOuts, DdManager **DdNew)
int CompareMinterms(int *ptrX, int *ptrY)
DdNode * cuddBddTransferPermute(DdManager *ddS, DdManager *ddD, DdNode *f, int *Permute)
#define MAXINPUTS
INCLUDES ///.
ABC_DLL int Cmd_CommandExecute(Abc_Frame_t *pAbc, const char *sCommand)
int st__gen(st__generator *gen, const char **key_p, char **value_p)
int st__ptrhash(const char *, int)
int st__ptrcmp(const char *, const char *)
void st__free_gen(st__generator *gen)
int st__find(st__table *table, char *key, char ***slot)
int st__lookup(st__table *table, const char *key, char **value)
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
st__generator * st__init_gen(st__table *table)
int st__add_direct(st__table *table, char *key, char *value)
void st__free_table(st__table *table)