src/bdd/cas/casCore.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "extra.h"
#include "cas.h"
Include dependency graph for casCore.c:

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

DdNodeGetSingleOutputFunction (DdManager *dd, DdNode **pbOuts, int nOuts, DdNode **pbVarsEnc, int nVarsEnc, int fVerbose)
DdNodeGetSingleOutputFunctionRemapped (DdManager *dd, DdNode **pOutputs, int nOuts, DdNode **pbVarsEnc, int nVarsEnc)
DdNodeGetSingleOutputFunctionRemappedNewDD (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)
DdNodeCudd_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))
DdNodecuddBddTransferPermute (DdManager *ddS, DdManager *ddD, DdNode *f, int *Permute)
static DdNodecuddBddTransferPermuteRecur (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 DdManagers_ddmin

Define Documentation

#define PRB (  )     printf( #f " = " ); Cudd_bddPrint(dd,f); printf( "\n" )

Definition at line 55 of file casCore.c.

#define PRD (  )     printf( "\nDECOMPOSITION TREE:\n\n" ); PrintDecEntry( (p), 0 )

static varibles /// debugging macros ///

Definition at line 54 of file casCore.c.

#define PRK ( f,
 )     Cudd_PrintKMap(stdout,dd,(f),Cudd_Not(f),(n),NULL,0); printf( "K-map for function" #f "\n\n" )

Definition at line 56 of file casCore.c.

#define PRK2 ( f,
g,
 )     Cudd_PrintKMap(stdout,dd,(f),(g),(n),NULL,0); printf( "K-map for function <" #f ", " #g ">\n\n" )

Definition at line 57 of file casCore.c.


Function Documentation

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 */

DdNode* cuddBddTransferPermute ( DdManager ddS,
DdManager ddD,
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. 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 [

Id
casCore.c,v 1.0 2002/01/01 00:00:00 alanmi Exp

] 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  ) 

Function********************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 490 of file casCore.c.

00491 { 
00492   return BinCode ^ ( BinCode >> 1 );
00493 }

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 }


Variable Documentation

unsigned char BitCount8[256] [static]
Initial value:
 {
    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 ///

Definition at line 462 of file casCore.c.

DdManager* s_ddmin [static]

Definition at line 927 of file casCore.c.

int s_MintOnes[MAXOUTPUTS] [static]

Definition at line 483 of file casCore.c.

int s_SuppSize[MAXOUTPUTS] [static]

Definition at line 474 of file casCore.c.


Generated on Tue Jan 5 12:18:51 2010 for abc70930 by  doxygen 1.6.1