#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "extra.h"
#include "cas.h"
Go to the source code of this file.
Defines | |
#define | PRD(p) printf( "\nDECOMPOSITION TREE:\n\n" ); PrintDecEntry( (p), 0 ) |
#define | PRB(f) printf( #f " = " ); Cudd_bddPrint(dd,f); printf( "\n" ) |
#define | PRK(f, n) Cudd_PrintKMap(stdout,dd,(f),Cudd_Not(f),(n),NULL,0); printf( "K-map for function" #f "\n\n" ) |
#define | PRK2(f, g, n) Cudd_PrintKMap(stdout,dd,(f),(g),(n),NULL,0); printf( "K-map for function <" #f ", " #g ">\n\n" ) |
Functions | |
DdNode * | GetSingleOutputFunction (DdManager *dd, DdNode **pbOuts, int nOuts, DdNode **pbVarsEnc, int nVarsEnc, int fVerbose) |
DdNode * | GetSingleOutputFunctionRemapped (DdManager *dd, DdNode **pOutputs, int nOuts, DdNode **pbVarsEnc, int nVarsEnc) |
DdNode * | GetSingleOutputFunctionRemappedNewDD (DdManager *dd, DdNode **pOutputs, int nOuts, DdManager **DdNew) |
int | CreateDecomposedNetwork (DdManager *dd, DdNode *aFunc, char **pNames, int nNames, char *FileName, int nLutSize, int fCheck, int fVerbose) |
void | WriteSingleOutputFunctionBlif (DdManager *dd, DdNode *aFunc, char **pNames, int nNames, char *FileName) |
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) |
int | CompareSupports (int *ptrX, int *ptrY) |
int | CompareMinterms (int *ptrX, int *ptrY) |
int | GrayCode (int BinCode) |
void | WriteDDintoBLIFfile (FILE *pFile, DdNode *Func, char *OutputName, char *Prefix, char **InputNames) |
void | WriteDDintoBLIFfileReorder (DdManager *dd, FILE *pFile, DdNode *Func, char *OutputName, char *Prefix, char **InputNames) |
static DdNode *cuddBddTransferPermuteRecur | ARGS ((DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table, int *Permute)) |
static DdNode *cuddBddTransferPermute | ARGS ((DdManager *ddS, DdManager *ddD, DdNode *f, int *Permute)) |
DdNode * | cuddBddTransferPermute (DdManager *ddS, DdManager *ddD, DdNode *f, int *Permute) |
static DdNode * | cuddBddTransferPermuteRecur (DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table, int *Permute) |
Variables | |
static unsigned char | BitCount8 [256] |
static int | s_SuppSize [MAXOUTPUTS] |
static int | s_MintOnes [MAXOUTPUTS] |
static DdManager * | s_ddmin |
#define PRB | ( | f | ) | printf( #f " = " ); Cudd_bddPrint(dd,f); printf( "\n" ) |
#define PRD | ( | p | ) | printf( "\nDECOMPOSITION TREE:\n\n" ); PrintDecEntry( (p), 0 ) |
#define PRK | ( | f, | |||
n | ) | Cudd_PrintKMap(stdout,dd,(f),Cudd_Not(f),(n),NULL,0); printf( "K-map for function" #f "\n\n" ) |
#define PRK2 | ( | f, | |||
g, | |||||
n | ) | Cudd_PrintKMap(stdout,dd,(f),(g),(n),NULL,0); printf( "K-map for function <" #f ", " #g ">\n\n" ) |
int Abc_CascadeExperiment | ( | char * | pFileGeneric, | |
DdManager * | dd, | |||
DdNode ** | pOutputs, | |||
int | nInputs, | |||
int | nOutputs, | |||
int | nLutSize, | |||
int | fCheck, | |||
int | fVerbose | |||
) |
EXTERNAL FUNCTIONS ///Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 75 of file casCore.c.
00076 { 00077 int i; 00078 int nVars = nInputs; 00079 int nOuts = nOutputs; 00080 long clk1; 00081 00082 int nVarsEnc; // the number of additional variables to encode outputs 00083 DdNode * pbVarsEnc[MAXOUTPUTS]; // the BDDs of the encoding vars 00084 00085 int nNames; // the total number of all inputs 00086 char * pNames[MAXINPUTS]; // the temporary storage for the input (and output encoding) names 00087 00088 DdNode * aFunc; // the encoded 0-1 BDD containing all the outputs 00089 00090 char FileNameIni[100]; 00091 char FileNameFin[100]; 00092 char Buffer[100]; 00093 00094 00095 //pTable = fopen( "stats.txt", "a+" ); 00096 //fprintf( pTable, "%s ", pFileGeneric ); 00097 //fprintf( pTable, "%d ", nVars ); 00098 //fprintf( pTable, "%d ", nOuts ); 00099 00100 00101 // assign the file names 00102 strcpy( FileNameIni, pFileGeneric ); 00103 strcat( FileNameIni, "_ENC.blif" ); 00104 00105 strcpy( FileNameFin, pFileGeneric ); 00106 strcat( FileNameFin, "_LUT.blif" ); 00107 00108 00109 // create the variables to encode the outputs 00110 nVarsEnc = Extra_Base2Log( nOuts ); 00111 for ( i = 0; i < nVarsEnc; i++ ) 00112 pbVarsEnc[i] = Cudd_bddNewVarAtLevel( dd, i ); 00113 00114 00115 // store the input names 00116 nNames = nVars + nVarsEnc; 00117 for ( i = 0; i < nVars; i++ ) 00118 { 00119 // pNames[i] = Extra_UtilStrsav( pFunc->pInputNames[i] ); 00120 sprintf( Buffer, "pi%03d", i ); 00121 pNames[i] = Extra_UtilStrsav( Buffer ); 00122 } 00123 // set the encoding variable name 00124 for ( ; i < nNames; i++ ) 00125 { 00126 sprintf( Buffer, "OutEnc_%02d", i-nVars ); 00127 pNames[i] = Extra_UtilStrsav( Buffer ); 00128 } 00129 00130 00131 // print the variable order 00132 // printf( "\n" ); 00133 // printf( "Variable order is: " ); 00134 // for ( i = 0; i < dd->size; i++ ) 00135 // printf( " %d", dd->invperm[i] ); 00136 // printf( "\n" ); 00137 00138 // derive the single-output function 00139 clk1 = clock(); 00140 aFunc = GetSingleOutputFunction( dd, pOutputs, nOuts, pbVarsEnc, nVarsEnc, fVerbose ); Cudd_Ref( aFunc ); 00141 // aFunc = GetSingleOutputFunctionRemapped( dd, pOutputs, nOuts, pbVarsEnc, nVarsEnc ); Cudd_Ref( aFunc ); 00142 // if ( fVerbose ) 00143 // printf( "Single-output function computation time = %.2f sec\n", (float)(clock() - clk1)/(float)(CLOCKS_PER_SEC) ); 00144 00145 //fprintf( pTable, "%d ", Cudd_SharingSize( pOutputs, nOutputs ) ); 00146 //fprintf( pTable, "%d ", Extra_ProfileWidthSharingMax(dd, pOutputs, nOutputs) ); 00147 00148 // dispose of the multiple-output function 00149 // Extra_Dissolve( pFunc ); 00150 00151 // reorder the single output function 00152 // if ( fVerbose ) 00153 // printf( "Reordering variables...\n"); 00154 clk1 = clock(); 00155 // if ( fVerbose ) 00156 // printf( "Node count before = %6d\n", Cudd_DagSize( aFunc ) ); 00157 // Cudd_ReduceHeap(dd, CUDD_REORDER_SIFT,1); 00158 Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1); 00159 Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1); 00160 // Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1); 00161 // Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1); 00162 // Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1); 00163 // Cudd_ReduceHeap(dd, CUDD_REORDER_SYMM_SIFT,1); 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 // printf( "\n" ); 00169 // printf( "Variable order is: " ); 00170 // for ( i = 0; i < dd->size; i++ ) 00171 // printf( " %d", dd->invperm[i] ); 00172 // printf( "\n" ); 00173 //fprintf( pTable, "%d ", Cudd_DagSize( aFunc ) ); 00174 //fprintf( pTable, "%d ", Extra_ProfileWidthMax(dd, aFunc) ); 00175 00176 // write the single-output function into BLIF for verification 00177 clk1 = clock(); 00178 if ( fCheck ) 00179 WriteSingleOutputFunctionBlif( dd, aFunc, pNames, nNames, FileNameIni ); 00180 // if ( fVerbose ) 00181 // printf( "Single-output function writing time = %.2f sec\n", (float)(clock() - clk1)/(float)(CLOCKS_PER_SEC) ); 00182 00183 /* 00185 // verification of single output function 00186 clk1 = clock(); 00187 { 00188 BFunc g_Func; 00189 DdNode * aRes; 00190 00191 g_Func.dd = dd; 00192 g_Func.FileInput = Extra_UtilStrsav(FileNameIni); 00193 00194 if ( Extra_ReadFile( &g_Func ) == 0 ) 00195 { 00196 printf( "\nSomething did not work out while reading the input file for verification\n"); 00197 Extra_Dissolve( &g_Func ); 00198 return; 00199 } 00200 00201 aRes = Cudd_BddToAdd( dd, g_Func.pOutputs[0] ); Cudd_Ref( aRes ); 00202 00203 if ( aRes != aFunc ) 00204 printf( "\nVerification FAILED!\n"); 00205 else 00206 printf( "\nVerification okay!\n"); 00207 00208 Cudd_RecursiveDeref( dd, aRes ); 00209 00210 // delocate 00211 Extra_Dissolve( &g_Func ); 00212 } 00213 printf( "Preliminary verification time = %.2f sec\n", (float)(clock() - clk1)/(float)(CLOCKS_PER_SEC) ); 00215 */ 00216 00217 if ( !CreateDecomposedNetwork( dd, aFunc, pNames, nNames, FileNameFin, nLutSize, fCheck, fVerbose ) ) 00218 return 0; 00219 00220 /* 00222 // verification of the decomposed LUT network 00223 clk1 = clock(); 00224 { 00225 BFunc g_Func; 00226 DdNode * aRes; 00227 00228 g_Func.dd = dd; 00229 g_Func.FileInput = Extra_UtilStrsav(FileNameFin); 00230 00231 if ( Extra_ReadFile( &g_Func ) == 0 ) 00232 { 00233 printf( "\nSomething did not work out while reading the input file for verification\n"); 00234 Extra_Dissolve( &g_Func ); 00235 return; 00236 } 00237 00238 aRes = Cudd_BddToAdd( dd, g_Func.pOutputs[0] ); Cudd_Ref( aRes ); 00239 00240 if ( aRes != aFunc ) 00241 printf( "\nFinal verification FAILED!\n"); 00242 else 00243 printf( "\nFinal verification okay!\n"); 00244 00245 Cudd_RecursiveDeref( dd, aRes ); 00246 00247 // delocate 00248 Extra_Dissolve( &g_Func ); 00249 } 00250 printf( "Final verification time = %.2f sec\n", (float)(clock() - clk1)/(float)(CLOCKS_PER_SEC) ); 00252 */ 00253 00254 // verify the results 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 // release the names 00267 for ( i = 0; i < nNames; i++ ) 00268 free( pNames[i] ); 00269 00270 00271 //fprintf( pTable, "\n" ); 00272 //fclose( pTable ); 00273 00274 return 1; 00275 }
static DdNode* cuddBddTransferPermute ARGS | ( | (DdManager *ddS, DdManager *ddD, DdNode *f, int *Permute) | ) | [static] |
static DdNode* cuddBddTransferPermuteRecur ARGS | ( | (DdManager *ddS, DdManager *ddD, DdNode *f, st_table *table, int *Permute) | ) | [static] |
TRANSFER WITH MAPPING ///
int CompareMinterms | ( | int * | ptrX, | |
int * | ptrY | |||
) |
Definition at line 484 of file casCore.c.
00485 { 00486 return ( s_MintOnes[*ptrY] - s_MintOnes[*ptrX] ); 00487 }
int CompareSupports | ( | int * | ptrX, | |
int * | ptrY | |||
) |
Definition at line 475 of file casCore.c.
00476 { 00477 return ( s_SuppSize[*ptrY] - s_SuppSize[*ptrX] ); 00478 }
int CreateDecomposedNetwork | ( | DdManager * | dd, | |
DdNode * | aFunc, | |||
char ** | pNames, | |||
int | nNames, | |||
char * | FileName, | |||
int | nLutSize, | |||
int | fCheck, | |||
int | fVerbose | |||
) |
EXTERNAL FUNCTIONS ///
Definition at line 106 of file casDec.c.
00111 { 00112 static LUT * pLuts[MAXINPUTS]; // the LUT cascade 00113 static int Profile[MAXINPUTS]; // the profile filled in with the info about the BDD width 00114 static int Permute[MAXINPUTS]; // the array to store a temporary permutation of variables 00115 00116 LUT * p; // the current LUT 00117 int i, v; 00118 00119 DdNode * bCVars[32]; // these are variables for the codes 00120 00121 int nVarsRem; // the number of remaining variables 00122 int PrevMulti; // column multiplicity on the previous level 00123 int fLastLut; // flag to signal the last LUT 00124 int nLuts; 00125 int nLutsTotal = 0; 00126 int nLutOutputs = 0; 00127 int nLutOutputsOrig = 0; 00128 00129 long clk1; 00130 00131 s_LutSize = nLutSize; 00132 00133 s_nFuncVars = nNames; 00134 00135 // get the profile 00136 clk1 = clock(); 00137 Extra_ProfileWidth( dd, aFunc, Profile, -1 ); 00138 00139 00140 // for ( v = 0; v < nNames; v++ ) 00141 // printf( "Level = %2d, Width = %2d\n", v+1, Profile[v] ); 00142 00143 00144 //printf( "\n" ); 00145 00146 // mark-up the LUTs 00147 // assuming that the manager has exactly nNames vars (new vars have not been introduced yet) 00148 nVarsRem = nNames; // the number of remaining variables 00149 PrevMulti = 0; // column multiplicity on the previous level 00150 fLastLut = 0; 00151 nLuts = 0; 00152 do 00153 { 00154 p = (LUT*) malloc( sizeof(LUT) ); 00155 memset( p, 0, sizeof(LUT) ); 00156 00157 if ( nVarsRem + PrevMulti <= s_LutSize ) // this is the last LUT 00158 { 00159 p->nIns = nVarsRem + PrevMulti; 00160 p->nInsP = PrevMulti; 00161 p->nCols = 2; 00162 p->nMulti = 1; 00163 p->Level = nNames-nVarsRem; 00164 00165 nVarsRem = 0; 00166 PrevMulti = 1; 00167 00168 fLastLut = 1; 00169 } 00170 else // this is not the last LUT 00171 { 00172 p->nIns = s_LutSize; 00173 p->nInsP = PrevMulti; 00174 p->nCols = Profile[nNames-(nVarsRem-(s_LutSize-PrevMulti))]; 00175 p->nMulti = Extra_Base2Log(p->nCols); 00176 p->Level = nNames-nVarsRem; 00177 00178 nVarsRem = nVarsRem-(s_LutSize-PrevMulti); 00179 PrevMulti = p->nMulti; 00180 } 00181 00182 if ( p->nMulti >= s_LutSize ) 00183 { 00184 printf( "The LUT size is too small\n" ); 00185 return 0; 00186 } 00187 00188 nLutOutputsOrig += p->nMulti; 00189 00190 00191 //if ( fVerbose ) 00192 //printf( "Stage %2d: In = %3d, InP = %3d, Cols = %5d, Multi = %2d, Level = %2d\n", 00193 // nLuts+1, p->nIns, p->nInsP, p->nCols, p->nMulti, p->Level ); 00194 00195 00196 // there should be as many columns, codes, and nodes, as there are columns on this level 00197 p->pbCols = (DdNode **) malloc( p->nCols * sizeof(DdNode *) ); 00198 p->pbCodes = (DdNode **) malloc( p->nCols * sizeof(DdNode *) ); 00199 p->paNodes = (DdNode **) malloc( p->nCols * sizeof(DdNode *) ); 00200 00201 pLuts[nLuts] = p; 00202 nLuts++; 00203 } 00204 while ( !fLastLut ); 00205 00206 00207 //if ( fVerbose ) 00208 //printf( "The number of cascades = %d\n", nLuts ); 00209 00210 00211 //fprintf( pTable, "%d ", nLuts ); 00212 00213 00214 // add the new variables at the bottom 00215 for ( i = 0; i < s_LutSize; i++ ) 00216 bCVars[i] = Cudd_bddNewVar(dd); 00217 00218 // for each LUT - assign the LUT and encode the columns 00219 s_EncodingTime = 0; 00220 for ( i = 0; i < nLuts; i++ ) 00221 { 00222 int RetValue; 00223 DdNode * bVars[32]; 00224 int nVars; 00225 DdNode * bVarsInCube; 00226 DdNode * bVarsCCube; 00227 DdNode * bVarsCube; 00228 int CutLevel; 00229 00230 p = pLuts[i]; 00231 00232 // compute the columns of this LUT starting from the given set of nodes with the given codes 00233 // (these codes have been remapped to depend on the topmost variables in the manager) 00234 // for the first LUT, start with the constant 1 BDD 00235 CutLevel = p->Level + p->nIns - p->nInsP; 00236 if ( i == 0 ) 00237 RetValue = Extra_bddNodePathsUnderCutArray( 00238 dd, &aFunc, &(b1), 1, 00239 p->paNodes, p->pbCols, CutLevel ); 00240 else 00241 RetValue = Extra_bddNodePathsUnderCutArray( 00242 dd, pLuts[i-1]->paNodes, pLuts[i-1]->pbCodes, pLuts[i-1]->nCols, 00243 p->paNodes, p->pbCols, CutLevel ); 00244 assert( RetValue == p->nCols ); 00245 // at this point, we have filled out p->paNodes[] and p->pbCols[] of this LUT 00246 // pLuts[i-1]->paNodes depended on normal vars 00247 // pLuts[i-1]->pbCodes depended on the topmost variables 00248 // the resulting p->paNodes depend on normal ADD nodes 00249 // the resulting p->pbCols depend on normal vars and topmost variables in the manager 00250 00251 // perform the encoding 00252 00253 // create the cube of these variables 00254 // collect the topmost variables of the manager 00255 nVars = p->nInsP; 00256 for ( v = 0; v < nVars; v++ ) 00257 bVars[v] = dd->vars[ dd->invperm[v] ]; 00258 bVarsCCube = Extra_bddBitsToCube( dd, (1<<nVars)-1, nVars, bVars, 1 ); Cudd_Ref( bVarsCCube ); 00259 00260 // collect the primary input variables involved in this LUT 00261 nVars = p->nIns - p->nInsP; 00262 for ( v = 0; v < nVars; v++ ) 00263 bVars[v] = dd->vars[ dd->invperm[p->Level+v] ]; 00264 bVarsInCube = Extra_bddBitsToCube( dd, (1<<nVars)-1, nVars, bVars, 1 ); Cudd_Ref( bVarsInCube ); 00265 00266 // get the cube 00267 bVarsCube = Cudd_bddAnd( dd, bVarsInCube, bVarsCCube ); Cudd_Ref( bVarsCube ); 00268 Cudd_RecursiveDeref( dd, bVarsInCube ); 00269 Cudd_RecursiveDeref( dd, bVarsCCube ); 00270 00271 // get the encoding relation 00272 if ( i == nLuts -1 ) 00273 { 00274 DdNode * bVar; 00275 assert( p->nMulti == 1 ); 00276 assert( p->nCols == 2 ); 00277 assert( Cudd_IsConstant( p->paNodes[0] ) ); 00278 assert( Cudd_IsConstant( p->paNodes[1] ) ); 00279 00280 bVar = ( p->paNodes[0] == a1 )? bCVars[0]: Cudd_Not( bCVars[0] ); 00281 p->bRelation = Cudd_bddIte( dd, bVar, p->pbCols[0], p->pbCols[1] ); Cudd_Ref( p->bRelation ); 00282 } 00283 else 00284 { 00285 long clk2 = clock(); 00286 // p->bRelation = PerformTheEncoding( dd, p->pbCols, p->nCols, bVarsCube, bCVars, p->nMulti, &p->nSimple ); Cudd_Ref( p->bRelation ); 00287 p->bRelation = Extra_bddEncodingNonStrict( dd, p->pbCols, p->nCols, bVarsCube, bCVars, p->nMulti, &p->nSimple ); Cudd_Ref( p->bRelation ); 00288 s_EncodingTime += clock() - clk2; 00289 } 00290 00291 // update the number of LUT outputs 00292 nLutOutputs += (p->nMulti - p->nSimple); 00293 nLutsTotal += p->nMulti; 00294 00295 //if ( fVerbose ) 00296 //printf( "Stage %2d: Simple = %d\n", i+1, p->nSimple ); 00297 00298 if ( fVerbose ) 00299 printf( "Stage %3d: In = %3d InP = %3d Cols = %5d Multi = %2d Simple = %2d Level = %3d\n", 00300 i+1, p->nIns, p->nInsP, p->nCols, p->nMulti, p->nSimple, p->Level ); 00301 00302 // get the codes from the relation (these are not necessarily cubes) 00303 { 00304 int c; 00305 for ( c = 0; c < p->nCols; c++ ) 00306 { 00307 p->pbCodes[c] = Cudd_bddAndAbstract( dd, p->bRelation, p->pbCols[c], bVarsCube ); Cudd_Ref( p->pbCodes[c] ); 00308 } 00309 } 00310 00311 Cudd_RecursiveDeref( dd, bVarsCube ); 00312 00313 // remap the codes to depend on the topmost varibles of the manager 00314 // useful as a preparation for the next step 00315 { 00316 DdNode ** pbTemp; 00317 int k, v; 00318 00319 pbTemp = (DdNode **) malloc( p->nCols * sizeof(DdNode *) ); 00320 00321 // create the identical permutation 00322 for ( v = 0; v < dd->size; v++ ) 00323 Permute[v] = v; 00324 00325 // use the topmost variables of the manager 00326 // to represent the previous level codes 00327 for ( v = 0; v < p->nMulti; v++ ) 00328 Permute[bCVars[v]->index] = dd->invperm[v]; 00329 00330 Extra_bddPermuteArray( dd, p->pbCodes, pbTemp, p->nCols, Permute ); 00331 // the array pbTemp comes already referenced 00332 00333 // deref the old codes and assign the new ones 00334 for ( k = 0; k < p->nCols; k++ ) 00335 { 00336 Cudd_RecursiveDeref( dd, p->pbCodes[k] ); 00337 p->pbCodes[k] = pbTemp[k]; 00338 } 00339 free( pbTemp ); 00340 } 00341 } 00342 if ( fVerbose ) 00343 printf( "LUTs: Total = %5d. Final = %5d. Simple = %5d. (%6.2f %%) ", 00344 nLutsTotal, nLutOutputs, nLutsTotal-nLutOutputs, 100.0*(nLutsTotal-nLutOutputs)/nLutsTotal ); 00345 if ( fVerbose ) 00346 printf( "Memory = %6.2f Mb\n", 1.0*nLutOutputs*(1<<nLutSize)/(1<<20) ); 00347 // printf( "\n" ); 00348 00349 //fprintf( pTable, "%d ", nLutOutputsOrig ); 00350 //fprintf( pTable, "%d ", nLutOutputs ); 00351 00352 if ( fVerbose ) 00353 { 00354 printf( "Pure decomposition time = %.2f sec\n", (float)(clock() - clk1 - s_EncodingTime)/(float)(CLOCKS_PER_SEC) ); 00355 printf( "Encoding time = %.2f sec\n", (float)(s_EncodingTime)/(float)(CLOCKS_PER_SEC) ); 00356 // printf( "Encoding search time = %.2f sec\n", (float)(s_EncSearchTime)/(float)(CLOCKS_PER_SEC) ); 00357 // printf( "Encoding compute time = %.2f sec\n", (float)(s_EncComputeTime)/(float)(CLOCKS_PER_SEC) ); 00358 } 00359 00360 00361 //fprintf( pTable, "%.2f ", (float)(s_ReadingTime)/(float)(CLOCKS_PER_SEC) ); 00362 //fprintf( pTable, "%.2f ", (float)(clock() - clk1 - s_EncodingTime)/(float)(CLOCKS_PER_SEC) ); 00363 //fprintf( pTable, "%.2f ", (float)(s_EncodingTime)/(float)(CLOCKS_PER_SEC) ); 00364 //fprintf( pTable, "%.2f ", (float)(s_RemappingTime)/(float)(CLOCKS_PER_SEC) ); 00365 00366 00367 // write LUTs into the BLIF file 00368 clk1 = clock(); 00369 if ( fCheck ) 00370 { 00371 FILE * pFile; 00372 // start the file 00373 pFile = fopen( FileName, "w" ); 00374 fprintf( pFile, ".model %s\n", FileName ); 00375 00376 fprintf( pFile, ".inputs" ); 00377 for ( i = 0; i < nNames; i++ ) 00378 fprintf( pFile, " %s", pNames[i] ); 00379 fprintf( pFile, "\n" ); 00380 fprintf( pFile, ".outputs F" ); 00381 fprintf( pFile, "\n" ); 00382 00383 // write the DD into the file 00384 WriteLUTSintoBLIFfile( pFile, dd, pLuts, nLuts, bCVars, pNames, nNames, FileName ); 00385 00386 fprintf( pFile, ".end\n" ); 00387 fclose( pFile ); 00388 if ( fVerbose ) 00389 printf( "Output file writing time = %.2f sec\n", (float)(clock() - clk1)/(float)(CLOCKS_PER_SEC) ); 00390 } 00391 00392 00393 // updo the LUT cascade 00394 for ( i = 0; i < nLuts; i++ ) 00395 { 00396 p = pLuts[i]; 00397 for ( v = 0; v < p->nCols; v++ ) 00398 { 00399 Cudd_RecursiveDeref( dd, p->pbCols[v] ); 00400 Cudd_RecursiveDeref( dd, p->pbCodes[v] ); 00401 Cudd_RecursiveDeref( dd, p->paNodes[v] ); 00402 } 00403 Cudd_RecursiveDeref( dd, p->bRelation ); 00404 00405 free( p->pbCols ); 00406 free( p->pbCodes ); 00407 free( p->paNodes ); 00408 free( p ); 00409 } 00410 00411 return 1; 00412 }
DdNode * Cudd_bddTransferPermute | ( | DdManager * | ddSource, | |
DdManager * | ddDestination, | |||
DdNode * | f, | |||
int * | Permute | |||
) |
Function********************************************************************
Synopsis [Convert a BDD from a manager to another one.]
Description [Convert a BDD from a manager to another one. The orders of the variables in the two managers may be different. Returns a pointer to the BDD in the destination manager if successful; NULL otherwise. The i-th entry in the array Permute tells what is the index of the i-th variable from the old manager in the new manager.]
SideEffects [None]
SeeAlso []
Definition at line 1094 of file casCore.c.
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 } /* end of Cudd_bddTransferPermute */
Function********************************************************************
Synopsis [Convert a BDD from a manager to another one.]
Description [Convert a BDD from a manager to another one. Returns a pointer to the BDD in the destination manager if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [Cudd_bddTransferPermute]
Definition at line 1128 of file casCore.c.
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 /* Dereference all elements in the table and dispose of the table. 01143 ** This must be done also if res is NULL to avoid leaks in case of 01144 ** reordering. */ 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 } /* end of cuddBddTransferPermute */
static DdNode* cuddBddTransferPermuteRecur | ( | DdManager * | ddS, | |
DdManager * | ddD, | |||
DdNode * | f, | |||
st_table * | table, | |||
int * | Permute | |||
) | [static] |
Function********************************************************************
Synopsis [Performs the recursive step of Cudd_bddTransferPermute.]
Description [Performs the recursive step of Cudd_bddTransferPermute. Returns a pointer to the result if successful; NULL otherwise.]
SideEffects [None]
SeeAlso [cuddBddTransferPermute]
Definition at line 1184 of file casCore.c.
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 /* Trivial cases. */ 01197 if ( Cudd_IsConstant( f ) ) 01198 return ( Cudd_NotCond( one, comple ) ); 01199 01200 /* Make canonical to increase the utilization of the cache. */ 01201 f = Cudd_NotCond( f, comple ); 01202 /* Now f is a regular pointer to a non-constant node. */ 01203 01204 /* Check the cache. */ 01205 if ( st_lookup( table, ( char * ) f, ( char ** ) &res ) ) 01206 return ( Cudd_NotCond( res, comple ) ); 01207 01208 /* Recursive step. */ 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 } /* end of cuddBddTransferPermuteRecur */
DdNode * GetSingleOutputFunction | ( | DdManager * | dd, | |
DdNode ** | pbOuts, | |||
int | nOuts, | |||
DdNode ** | pbVarsEnc, | |||
int | nVarsEnc, | |||
int | fVerbose | |||
) |
CFile****************************************************************
FileName [casCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [CASCADE: Decomposition of shared BDDs into a LUT cascade.]
Synopsis [Entrance into the implementation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - Spring 2002.]
Revision [
] static functions ///
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 506 of file casCore.c.
00507 { 00508 int i; 00509 DdNode * bResult, * aResult; 00510 DdNode * bCube, * bTemp, * bProd; 00511 00512 int Order[MAXOUTPUTS]; 00513 // int OrderMint[MAXOUTPUTS]; 00514 00515 // sort the output according to their support size 00516 for ( i = 0; i < nOuts; i++ ) 00517 { 00518 s_SuppSize[i] = Cudd_SupportSize( dd, pbOuts[i] ); 00519 // s_MintOnes[i] = BitCount8[i]; 00520 Order[i] = i; 00521 // OrderMint[i] = i; 00522 } 00523 00524 // order the outputs 00525 qsort( (void*)Order, nOuts, sizeof(int), (int(*)(const void*, const void*)) CompareSupports ); 00526 // order the outputs 00527 // qsort( (void*)OrderMint, nOuts, sizeof(int), (int(*)(const void*, const void*)) CompareMinterms ); 00528 00529 00530 bResult = b0; Cudd_Ref( bResult ); 00531 for ( i = 0; i < nOuts; i++ ) 00532 { 00533 // bCube = Cudd_bddBitsToCube( dd, OrderMint[i], nVarsEnc, pbVarsEnc ); Cudd_Ref( bCube ); 00534 // bProd = Cudd_bddAnd( dd, bCube, pbOuts[Order[nOuts-1-i]] ); Cudd_Ref( bProd ); 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 // convert to the ADD 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 }
DdNode * GetSingleOutputFunctionRemapped | ( | DdManager * | dd, | |
DdNode ** | pOutputs, | |||
int | nOuts, | |||
DdNode ** | pbVarsEnc, | |||
int | nVarsEnc | |||
) |
INPUT REMAPPING ///Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 600 of file casCore.c.
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 // perform the remapping 00615 for ( i = 0; i < nOuts; i++ ) 00616 { 00617 // get support 00618 bSupp = Cudd_Support( dd, pOutputs[i] ); Cudd_Ref( bSupp ); 00619 00620 // create the variable map 00621 Counter = 0; 00622 for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) ) 00623 Permute[bTemp->index] = Counter++; 00624 00625 // transfer the BDD and remap it 00626 pRemapped[i] = Cudd_bddPermute( dd, pOutputs[i], Permute ); Cudd_Ref( pRemapped[i] ); 00627 00628 // remove support 00629 Cudd_RecursiveDeref( dd, bSupp ); 00630 } 00631 00632 // perform the encoding 00633 bFunc = Extra_bddEncodingBinary( dd, pRemapped, nOuts, pbVarsEnc, nVarsEnc ); Cudd_Ref( bFunc ); 00634 00635 // convert to ADD 00636 aFunc = Cudd_BddToAdd( dd, bFunc ); Cudd_Ref( aFunc ); 00637 Cudd_RecursiveDeref( dd, bFunc ); 00638 00639 // deref the intermediate results 00640 for ( i = 0; i < nOuts; i++ ) 00641 Cudd_RecursiveDeref( dd, pRemapped[i] ); 00642 00643 Cudd_Deref( aFunc ); 00644 return aFunc; 00645 }
DdNode * GetSingleOutputFunctionRemappedNewDD | ( | DdManager * | dd, | |
DdNode ** | pOutputs, | |||
int | nOuts, | |||
DdManager ** | DdNew | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 659 of file casCore.c.
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 // these are in the new manager 00676 DdNode * bFuncNew; 00677 DdNode * aFuncNew; 00678 00679 int nVarsMax = 0; 00680 00681 // perform the remapping and write the DDs into the new manager 00682 for ( i = 0; i < nOuts; i++ ) 00683 { 00684 // get support 00685 bSupp = Cudd_Support( dd, pOutputs[i] ); Cudd_Ref( bSupp ); 00686 00687 // create the variable map 00688 // to remap the DD into the upper part of the manager 00689 Counter = 0; 00690 for ( bTemp = bSupp; bTemp != dd->one; bTemp = cuddT(bTemp) ) 00691 Permute[bTemp->index] = dd->invperm[Counter++]; 00692 00693 // transfer the BDD and remap it 00694 pRemapped[i] = Cudd_bddPermute( dd, pOutputs[i], Permute ); Cudd_Ref( pRemapped[i] ); 00695 00696 // remove support 00697 Cudd_RecursiveDeref( dd, bSupp ); 00698 00699 00700 // determine the largest support size 00701 if ( nVarsMax < Counter ) 00702 nVarsMax = Counter; 00703 } 00704 00705 // select the encoding variables to follow immediately after the original variables 00706 nVarsEnc = Extra_Base2Log(nOuts); 00707 /* 00708 for ( v = 0; v < nVarsEnc; v++ ) 00709 if ( nVarsMax + v < dd->size ) 00710 pbVarsEnc[v] = dd->var[ dd->invperm[nVarsMax+v] ]; 00711 else 00712 pbVarsEnc[v] = Cudd_bddNewVar( dd ); 00713 */ 00714 // create the new variables on top of the manager 00715 for ( v = 0; v < nVarsEnc; v++ ) 00716 pbVarsEnc[v] = Cudd_bddNewVarAtLevel( dd, v ); 00717 00718 //fprintf( pTable, "%d ", Cudd_SharingSize( pRemapped, nOuts ) ); 00719 //fprintf( pTable, "%d ", Extra_ProfileWidthSharingMax(dd, pRemapped, nOuts) ); 00720 00721 00722 // perform the encoding 00723 bFunc = Extra_bddEncodingBinary( dd, pRemapped, nOuts, pbVarsEnc, nVarsEnc ); Cudd_Ref( bFunc ); 00724 00725 00726 // find the cross-manager permutation 00727 // the variable from the level v in the old manager 00728 // should become a variable number v in the new manager 00729 for ( v = 0; v < nVarsMax + nVarsEnc; v++ ) 00730 Permute[dd->invperm[v]] = v; 00731 00732 00734 // start the new manager 00735 ddnew = Cudd_Init( nVarsMax + nVarsEnc, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); 00736 // Cudd_AutodynDisable(ddnew); 00737 Cudd_AutodynEnable(dd, CUDD_REORDER_SYMM_SIFT); 00738 00739 // transfer it to the new manager 00740 bFuncNew = Cudd_bddTransferPermute( dd, ddnew, bFunc, Permute ); Cudd_Ref( bFuncNew ); 00742 00743 00744 // deref the intermediate results in the old manager 00745 Cudd_RecursiveDeref( dd, bFunc ); 00746 for ( i = 0; i < nOuts; i++ ) 00747 Cudd_RecursiveDeref( dd, pRemapped[i] ); 00748 00749 00751 // convert to ADD in the new manager 00752 aFuncNew = Cudd_BddToAdd( ddnew, bFuncNew ); Cudd_Ref( aFuncNew ); 00753 Cudd_RecursiveDeref( ddnew, bFuncNew ); 00754 00755 // return the manager 00756 *DdNew = ddnew; 00758 00759 Cudd_Deref( aFuncNew ); 00760 return aFuncNew; 00761 }
int GrayCode | ( | int | BinCode | ) |
void WriteDDintoBLIFfile | ( | FILE * | pFile, | |
DdNode * | Func, | |||
char * | OutputName, | |||
char * | Prefix, | |||
char ** | InputNames | |||
) |
BLIF WRITING FUNCTIONS ///
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 815 of file casCore.c.
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 /* Initialize symbol table for visited nodes. */ 00830 visited = st_init_table( st_ptrcmp, st_ptrhash ); 00831 00832 /* Collect all the nodes of this DD in the symbol table. */ 00833 cuddCollectNodes( Cudd_Regular(Func), visited ); 00834 00835 /* Find how many most significant hex digits are identical 00836 ** in the addresses of all the nodes. Build a mask based 00837 ** on this knowledge, so that digits that carry no information 00838 ** will not be printed. This is done in two steps. 00839 ** 1. We scan the symbol table to find the bits that differ 00840 ** in at least 2 addresses. 00841 ** 2. We choose one of the possible masks. There are 8 possible 00842 ** masks for 32-bit integer, and 16 possible masks for 64-bit 00843 ** integers. 00844 */ 00845 00846 /* Find the bits that are different. */ 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 /* Choose the mask. */ 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 // write the buffer for the output 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 // write the terminal node 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 { // no inverter 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 { // inverter 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 // if the inverter is written, skip 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 }
void WriteDDintoBLIFfileReorder | ( | DdManager * | dd, | |
FILE * | pFile, | |||
DdNode * | Func, | |||
char * | OutputName, | |||
char * | Prefix, | |||
char ** | InputNames | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 940 of file casCore.c.
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 // reorder 00966 printf( "Nodes before = %d. ", Cudd_DagSize(bFmin) ); 00967 Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SYMM_SIFT,1); 00968 // Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SYMM_SIFT_CONV,1); 00969 printf( "Nodes after = %d. \n", Cudd_DagSize(bFmin) ); 00971 00972 00973 00974 /* Initialize symbol table for visited nodes. */ 00975 visited = st_init_table( st_ptrcmp, st_ptrhash ); 00976 00977 /* Collect all the nodes of this DD in the symbol table. */ 00978 cuddCollectNodes( Cudd_Regular(bFmin), visited ); 00979 00980 /* Find how many most significant hex digits are identical 00981 ** in the addresses of all the nodes. Build a mask based 00982 ** on this knowledge, so that digits that carry no information 00983 ** will not be printed. This is done in two steps. 00984 ** 1. We scan the symbol table to find the bits that differ 00985 ** in at least 2 addresses. 00986 ** 2. We choose one of the possible masks. There are 8 possible 00987 ** masks for 32-bit integer, and 16 possible masks for 64-bit 00988 ** integers. 00989 */ 00990 00991 /* Find the bits that are different. */ 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 /* Choose the mask. */ 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 // write the buffer for the output 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 // write the terminal node 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 { // no inverter 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 { // inverter 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 }
void WriteSingleOutputFunctionBlif | ( | DdManager * | dd, | |
DdNode * | aFunc, | |||
char ** | pNames, | |||
int | nNames, | |||
char * | FileName | |||
) |
Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
Definition at line 781 of file casCore.c.
00782 { 00783 int i; 00784 FILE * pFile; 00785 00786 // start the file 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 // write the DD into the file 00798 WriteDDintoBLIFfile( pFile, aFunc, "F", "", pNames ); 00799 00800 fprintf( pFile, ".end\n" ); 00801 fclose( pFile ); 00802 }
unsigned char BitCount8[256] [static] |
{ 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, 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, 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, 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, 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, 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, 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, 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 }
SINGLE OUTPUT FUNCTION ///
int s_MintOnes[MAXOUTPUTS] [static] |
int s_SuppSize[MAXOUTPUTS] [static] |