#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include "extra.h"
#include "cas.h"
Go to the source code of this file.
Data Structures | |
struct | LUT |
Defines | |
#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 | |
void | WriteLUTSintoBLIFfile (FILE *pFile, DdManager *dd, LUT **pLuts, int nLuts, DdNode **bCVars, char **pNames, int nNames, char *FileName) |
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) |
int | CreateDecomposedNetwork (DdManager *dd, DdNode *aFunc, char **pNames, int nNames, char *FileName, int nLutSize, int fCheck, int fVerbose) |
Variables | |
static int | s_LutSize = 15 |
static int | s_nFuncVars |
long | s_EncodingTime |
long | s_EncSearchTime |
long | s_EncComputeTime |
#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" ) |
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 }
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 WriteLUTSintoBLIFfile | ( | FILE * | pFile, | |
DdManager * | dd, | |||
LUT ** | pLuts, | |||
int | nLuts, | |||
DdNode ** | bCVars, | |||
char ** | pNames, | |||
int | nNames, | |||
char * | FileName | |||
) |
static functions ///
Definition at line 414 of file casDec.c.
00415 { 00416 int i, v, o; 00417 static char * pNamesLocalIn[MAXINPUTS]; 00418 static char * pNamesLocalOut[MAXINPUTS]; 00419 static char Buffer[100]; 00420 DdNode * bCube, * bCof, * bFunc; 00421 LUT * p; 00422 00423 // go through all the LUTs 00424 for ( i = 0; i < nLuts; i++ ) 00425 { 00426 // get the pointer to the LUT 00427 p = pLuts[i]; 00428 00429 if ( i == nLuts -1 ) 00430 { 00431 assert( p->nMulti == 1 ); 00432 } 00433 00434 00435 fprintf( pFile, "#----------------- LUT #%d ----------------------\n", i ); 00436 00437 00438 // fill in the names for the current LUT 00439 00440 // write the outputs of the previous LUT 00441 if ( i != 0 ) 00442 for ( v = 0; v < p->nInsP; v++ ) 00443 { 00444 sprintf( Buffer, "LUT%02d_%02d", i-1, v ); 00445 pNamesLocalIn[dd->invperm[v]] = Extra_UtilStrsav( Buffer ); 00446 } 00447 // write the primary inputs of the current LUT 00448 for ( v = 0; v < p->nIns - p->nInsP; v++ ) 00449 pNamesLocalIn[dd->invperm[p->Level+v]] = Extra_UtilStrsav( pNames[dd->invperm[p->Level+v]] ); 00450 // write the outputs of the current LUT 00451 for ( v = 0; v < p->nMulti; v++ ) 00452 { 00453 sprintf( Buffer, "LUT%02d_%02d", i, v ); 00454 if ( i != nLuts - 1 ) 00455 pNamesLocalOut[v] = Extra_UtilStrsav( Buffer ); 00456 else 00457 pNamesLocalOut[v] = Extra_UtilStrsav( "F" ); 00458 } 00459 00460 00461 // write LUT outputs 00462 00463 // get the prefix 00464 sprintf( Buffer, "L%02d_", i ); 00465 00466 // get the cube of encoding variables 00467 bCube = Extra_bddBitsToCube( dd, (1<<p->nMulti)-1, p->nMulti, bCVars, 1 ); Cudd_Ref( bCube ); 00468 00469 // write each output of the LUT 00470 for ( o = 0; o < p->nMulti; o++ ) 00471 { 00472 // get the cofactor of this output 00473 bCof = Cudd_Cofactor( dd, p->bRelation, bCVars[o] ); Cudd_Ref( bCof ); 00474 // quantify the remaining variables to get the function 00475 bFunc = Cudd_bddExistAbstract( dd, bCof, bCube ); Cudd_Ref( bFunc ); 00476 Cudd_RecursiveDeref( dd, bCof ); 00477 00478 // write BLIF 00479 sprintf( Buffer, "L%02d_%02d_", i, o ); 00480 00481 // WriteDDintoBLIFfileReorder( dd, pFile, bFunc, pNamesLocalOut[o], Buffer, pNamesLocalIn ); 00482 // does not work well; the advantage is marginal (30%), the run time is huge... 00483 00484 WriteDDintoBLIFfile( pFile, bFunc, pNamesLocalOut[o], Buffer, pNamesLocalIn ); 00485 Cudd_RecursiveDeref( dd, bFunc ); 00486 } 00487 Cudd_RecursiveDeref( dd, bCube ); 00488 00489 // clean up the previous local names 00490 for ( v = 0; v < dd->size; v++ ) 00491 { 00492 if ( pNamesLocalIn[v] ) 00493 free( pNamesLocalIn[v] ); 00494 pNamesLocalIn[v] = NULL; 00495 } 00496 for ( v = 0; v < p->nMulti; v++ ) 00497 free( pNamesLocalOut[v] ); 00498 } 00499 }
long s_EncComputeTime |
long s_EncodingTime |
long s_EncSearchTime |
int s_nFuncVars [static] |