ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
casDec.c File Reference
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "bdd/extrab/extraBdd.h"
#include "cas.h"
Include dependency graph for casDec.c:

Go to the source code of this file.

Classes

struct  LUT
 type definitions /// More...
 

Macros

#define PRB_(f)
 debugging macros ///
 
#define PRK(f, n)
 
#define PRK2(f, g, n)
 

Functions

void WriteLUTSintoBLIFfile (FILE *pFile, DdManager *dd, LUT **pLuts, int nLuts, DdNode **bCVars, char **pNames, int nNames, char *FileName)
 static functions ///
 
void WriteDDintoBLIFfile (FILE *pFile, DdNode *Func, char *OutputName, char *Prefix, char **InputNames)
 BLIF WRITING FUNCTIONS ///.
 
void WriteDDintoBLIFfileReorder (DdManager *dd, FILE *pFile, DdNode *Func, char *OutputName, char *Prefix, char **InputNames)
 
int CreateDecomposedNetwork (DdManager *dd, DdNode *aFunc, char **pNames, int nNames, char *FileName, int nLutSize, int fCheck, int fVerbose)
 EXTERNAL FUNCTIONS ///.
 

Variables

long s_EncodingTime
 
long s_EncSearchTime
 
long s_EncComputeTime
 

Macro Definition Documentation

◆ PRB_

#define PRB_ ( f)
Value:
printf( #f " = " ); Cudd_bddPrint(dd,f); printf( "\n" )

debugging macros ///

Definition at line 99 of file casDec.c.

◆ PRK

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

Definition at line 100 of file casDec.c.

◆ PRK2

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

Definition at line 101 of file casDec.c.

Function Documentation

◆ CreateDecomposedNetwork()

int CreateDecomposedNetwork ( DdManager * dd,
DdNode * aFunc,
char ** pNames,
int nNames,
char * FileName,
int nLutSize,
int fCheck,
int fVerbose )

EXTERNAL FUNCTIONS ///.

Definition at line 108 of file casDec.c.

113{
114 static LUT * pLuts[MAXINPUTS]; // the LUT cascade
115 static int Profile[MAXINPUTS]; // the profile filled in with the info about the BDD width
116 static int Permute[MAXINPUTS]; // the array to store a temporary permutation of variables
117
118 LUT * p; // the current LUT
119 int i, v;
120
121 DdNode * bCVars[32]; // these are variables for the codes
122
123 int nVarsRem; // the number of remaining variables
124 int PrevMulti; // column multiplicity on the previous level
125 int fLastLut; // flag to signal the last LUT
126 int nLuts;
127 int nLutsTotal = 0;
128 int nLutOutputs = 0;
129 int nLutOutputsOrig = 0;
130
131 abctime clk1;
132
133 s_LutSize = nLutSize;
134
135 s_nFuncVars = nNames;
136
137 // get the profile
138 clk1 = Abc_Clock();
139 Extra_ProfileWidth( dd, aFunc, Profile, -1 );
140
141
142// for ( v = 0; v < nNames; v++ )
143// printf( "Level = %2d, Width = %2d\n", v+1, Profile[v] );
144
145
146//printf( "\n" );
147
148 // mark-up the LUTs
149 // assuming that the manager has exactly nNames vars (new vars have not been introduced yet)
150 nVarsRem = nNames; // the number of remaining variables
151 PrevMulti = 0; // column multiplicity on the previous level
152 fLastLut = 0;
153 nLuts = 0;
154 do
155 {
156 p = (LUT*) ABC_ALLOC( char, sizeof(LUT) );
157 memset( p, 0, sizeof(LUT) );
158
159 if ( nVarsRem + PrevMulti <= s_LutSize ) // this is the last LUT
160 {
161 p->nIns = nVarsRem + PrevMulti;
162 p->nInsP = PrevMulti;
163 p->nCols = 2;
164 p->nMulti = 1;
165 p->Level = nNames-nVarsRem;
166
167 nVarsRem = 0;
168 PrevMulti = 1;
169
170 fLastLut = 1;
171 }
172 else // this is not the last LUT
173 {
174 p->nIns = s_LutSize;
175 p->nInsP = PrevMulti;
176 p->nCols = Profile[nNames-(nVarsRem-(s_LutSize-PrevMulti))];
177 p->nMulti = Abc_Base2Log(p->nCols);
178 p->Level = nNames-nVarsRem;
179
180 nVarsRem = nVarsRem-(s_LutSize-PrevMulti);
181 PrevMulti = p->nMulti;
182 }
183
184 if ( p->nMulti >= s_LutSize )
185 {
186 printf( "The LUT size is too small\n" );
187 return 0;
188 }
189
190 nLutOutputsOrig += p->nMulti;
191
192
193//if ( fVerbose )
194//printf( "Stage %2d: In = %3d, InP = %3d, Cols = %5d, Multi = %2d, Level = %2d\n",
195// nLuts+1, p->nIns, p->nInsP, p->nCols, p->nMulti, p->Level );
196
197
198 // there should be as many columns, codes, and nodes, as there are columns on this level
199 p->pbCols = (DdNode **) ABC_ALLOC( char, p->nCols * sizeof(DdNode *) );
200 p->pbCodes = (DdNode **) ABC_ALLOC( char, p->nCols * sizeof(DdNode *) );
201 p->paNodes = (DdNode **) ABC_ALLOC( char, p->nCols * sizeof(DdNode *) );
202
203 pLuts[nLuts] = p;
204 nLuts++;
205 }
206 while ( !fLastLut );
207
208
209//if ( fVerbose )
210//printf( "The number of cascades = %d\n", nLuts );
211
212
213//fprintf( pTable, "%d ", nLuts );
214
215
216 // add the new variables at the bottom
217 for ( i = 0; i < s_LutSize; i++ )
218 bCVars[i] = Cudd_bddNewVar(dd);
219
220 // for each LUT - assign the LUT and encode the columns
221 s_EncodingTime = 0;
222 for ( i = 0; i < nLuts; i++ )
223 {
224 int RetValue;
225 DdNode * bVars[32];
226 int nVars;
227 DdNode * bVarsInCube;
228 DdNode * bVarsCCube;
229 DdNode * bVarsCube;
230 int CutLevel;
231
232 p = pLuts[i];
233
234 // compute the columns of this LUT starting from the given set of nodes with the given codes
235 // (these codes have been remapped to depend on the topmost variables in the manager)
236 // for the first LUT, start with the constant 1 BDD
237 CutLevel = p->Level + p->nIns - p->nInsP;
238 if ( i == 0 )
240 dd, &aFunc, &(b1), 1,
241 p->paNodes, p->pbCols, CutLevel );
242 else
244 dd, pLuts[i-1]->paNodes, pLuts[i-1]->pbCodes, pLuts[i-1]->nCols,
245 p->paNodes, p->pbCols, CutLevel );
246 assert( RetValue == p->nCols );
247 // at this point, we have filled out p->paNodes[] and p->pbCols[] of this LUT
248 // pLuts[i-1]->paNodes depended on normal vars
249 // pLuts[i-1]->pbCodes depended on the topmost variables
250 // the resulting p->paNodes depend on normal ADD nodes
251 // the resulting p->pbCols depend on normal vars and topmost variables in the manager
252
253 // perform the encoding
254
255 // create the cube of these variables
256 // collect the topmost variables of the manager
257 nVars = p->nInsP;
258 for ( v = 0; v < nVars; v++ )
259 bVars[v] = dd->vars[ dd->invperm[v] ];
260 bVarsCCube = Extra_bddBitsToCube( dd, (1<<nVars)-1, nVars, bVars, 1 ); Cudd_Ref( bVarsCCube );
261
262 // collect the primary input variables involved in this LUT
263 nVars = p->nIns - p->nInsP;
264 for ( v = 0; v < nVars; v++ )
265 bVars[v] = dd->vars[ dd->invperm[p->Level+v] ];
266 bVarsInCube = Extra_bddBitsToCube( dd, (1<<nVars)-1, nVars, bVars, 1 ); Cudd_Ref( bVarsInCube );
267
268 // get the cube
269 bVarsCube = Cudd_bddAnd( dd, bVarsInCube, bVarsCCube ); Cudd_Ref( bVarsCube );
270 Cudd_RecursiveDeref( dd, bVarsInCube );
271 Cudd_RecursiveDeref( dd, bVarsCCube );
272
273 // get the encoding relation
274 if ( i == nLuts -1 )
275 {
276 DdNode * bVar;
277 assert( p->nMulti == 1 );
278 assert( p->nCols == 2 );
279 assert( Cudd_IsConstant( p->paNodes[0] ) );
280 assert( Cudd_IsConstant( p->paNodes[1] ) );
281
282 bVar = ( p->paNodes[0] == a1 )? bCVars[0]: Cudd_Not( bCVars[0] );
283 p->bRelation = Cudd_bddIte( dd, bVar, p->pbCols[0], p->pbCols[1] ); Cudd_Ref( p->bRelation );
284 }
285 else
286 {
287 abctime clk2 = Abc_Clock();
288// p->bRelation = PerformTheEncoding( dd, p->pbCols, p->nCols, bVarsCube, bCVars, p->nMulti, &p->nSimple ); Cudd_Ref( p->bRelation );
289 p->bRelation = Extra_bddEncodingNonStrict( dd, p->pbCols, p->nCols, bVarsCube, bCVars, p->nMulti, &p->nSimple ); Cudd_Ref( p->bRelation );
290 s_EncodingTime += Abc_Clock() - clk2;
291 }
292
293 // update the number of LUT outputs
294 nLutOutputs += (p->nMulti - p->nSimple);
295 nLutsTotal += p->nMulti;
296
297//if ( fVerbose )
298//printf( "Stage %2d: Simple = %d\n", i+1, p->nSimple );
299
300if ( fVerbose )
301printf( "Stage %3d: In = %3d InP = %3d Cols = %5d Multi = %2d Simple = %2d Level = %3d\n",
302 i+1, p->nIns, p->nInsP, p->nCols, p->nMulti, p->nSimple, p->Level );
303
304 // get the codes from the relation (these are not necessarily cubes)
305 {
306 int c;
307 for ( c = 0; c < p->nCols; c++ )
308 {
309 p->pbCodes[c] = Cudd_bddAndAbstract( dd, p->bRelation, p->pbCols[c], bVarsCube ); Cudd_Ref( p->pbCodes[c] );
310 }
311 }
312
313 Cudd_RecursiveDeref( dd, bVarsCube );
314
315 // remap the codes to depend on the topmost varibles of the manager
316 // useful as a preparation for the next step
317 {
318 DdNode ** pbTemp;
319 int k, v;
320
321 pbTemp = (DdNode **) ABC_ALLOC( char, p->nCols * sizeof(DdNode *) );
322
323 // create the identical permutation
324 for ( v = 0; v < dd->size; v++ )
325 Permute[v] = v;
326
327 // use the topmost variables of the manager
328 // to represent the previous level codes
329 for ( v = 0; v < p->nMulti; v++ )
330 Permute[bCVars[v]->index] = dd->invperm[v];
331
332 Extra_bddPermuteArray( dd, p->pbCodes, pbTemp, p->nCols, Permute );
333 // the array pbTemp comes already referenced
334
335 // deref the old codes and assign the new ones
336 for ( k = 0; k < p->nCols; k++ )
337 {
338 Cudd_RecursiveDeref( dd, p->pbCodes[k] );
339 p->pbCodes[k] = pbTemp[k];
340 }
341 ABC_FREE( pbTemp );
342 }
343 }
344 if ( fVerbose )
345 printf( "LUTs: Total = %5d. Final = %5d. Simple = %5d. (%6.2f %%) ",
346 nLutsTotal, nLutOutputs, nLutsTotal-nLutOutputs, 100.0*(nLutsTotal-nLutOutputs)/nLutsTotal );
347 if ( fVerbose )
348 printf( "Memory = %6.2f MB\n", 1.0*nLutOutputs*(1<<nLutSize)/(1<<20) );
349// printf( "\n" );
350
351//fprintf( pTable, "%d ", nLutOutputsOrig );
352//fprintf( pTable, "%d ", nLutOutputs );
353
354 if ( fVerbose )
355 {
356 printf( "Pure decomposition time = %.2f sec\n", (float)(Abc_Clock() - clk1 - s_EncodingTime)/(float)(CLOCKS_PER_SEC) );
357 printf( "Encoding time = %.2f sec\n", (float)(s_EncodingTime)/(float)(CLOCKS_PER_SEC) );
358// printf( "Encoding search time = %.2f sec\n", (float)(s_EncSearchTime)/(float)(CLOCKS_PER_SEC) );
359// printf( "Encoding compute time = %.2f sec\n", (float)(s_EncComputeTime)/(float)(CLOCKS_PER_SEC) );
360 }
361
362
363//fprintf( pTable, "%.2f ", (float)(s_ReadingTime)/(float)(CLOCKS_PER_SEC) );
364//fprintf( pTable, "%.2f ", (float)(Abc_Clock() - clk1 - s_EncodingTime)/(float)(CLOCKS_PER_SEC) );
365//fprintf( pTable, "%.2f ", (float)(s_EncodingTime)/(float)(CLOCKS_PER_SEC) );
366//fprintf( pTable, "%.2f ", (float)(s_RemappingTime)/(float)(CLOCKS_PER_SEC) );
367
368
369 // write LUTs into the BLIF file
370 clk1 = Abc_Clock();
371 if ( fCheck )
372 {
373 FILE * pFile;
374 // start the file
375 pFile = fopen( FileName, "w" );
376 fprintf( pFile, ".model %s\n", FileName );
377
378 fprintf( pFile, ".inputs" );
379 for ( i = 0; i < nNames; i++ )
380 fprintf( pFile, " %s", pNames[i] );
381 fprintf( pFile, "\n" );
382 fprintf( pFile, ".outputs F" );
383 fprintf( pFile, "\n" );
384
385 // write the DD into the file
386 WriteLUTSintoBLIFfile( pFile, dd, pLuts, nLuts, bCVars, pNames, nNames, FileName );
387
388 fprintf( pFile, ".end\n" );
389 fclose( pFile );
390 if ( fVerbose )
391 printf( "Output file writing time = %.2f sec\n", (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC) );
392 }
393
394
395 // updo the LUT cascade
396 for ( i = 0; i < nLuts; i++ )
397 {
398 p = pLuts[i];
399 for ( v = 0; v < p->nCols; v++ )
400 {
401 Cudd_RecursiveDeref( dd, p->pbCols[v] );
402 Cudd_RecursiveDeref( dd, p->pbCodes[v] );
403 Cudd_RecursiveDeref( dd, p->paNodes[v] );
404 }
405 Cudd_RecursiveDeref( dd, p->bRelation );
406
407 ABC_FREE( p->pbCols );
408 ABC_FREE( p->pbCodes );
409 ABC_FREE( p->paNodes );
410 ABC_FREE( p );
411 }
412
413 return 1;
414}
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_FREE(obj)
Definition abc_global.h:267
#define b1
Definition bbrImage.c:97
long s_EncodingTime
Definition casDec.c:83
void WriteLUTSintoBLIFfile(FILE *pFile, DdManager *dd, LUT **pLuts, int nLuts, DdNode **bCVars, char **pNames, int nNames, char *FileName)
static functions ///
Definition casDec.c:416
#define MAXINPUTS
INCLUDES ///.
Definition cas.h:38
Cube * p
Definition exorList.c:222
DdNode * Extra_bddBitsToCube(DdManager *dd, int Code, int CodeWidth, DdNode **pbVars, int fMsbFirst)
void Extra_bddPermuteArray(DdManager *dd, DdNode **bNodesIn, DdNode **bNodesOut, int nNodes, int *permut)
int Extra_ProfileWidth(DdManager *dd, DdNode *F, int *Profile, int CutLevel)
int Extra_bddNodePathsUnderCutArray(DdManager *dd, DdNode **paNodes, DdNode **pbCubes, int nNodes, DdNode **paNodesRes, DdNode **pbCubesRes, int CutLevel)
#define a1
Definition extraBdd.h:80
DdNode * Extra_bddEncodingNonStrict(DdManager *dd, DdNode **pbColumns, int nColumns, DdNode *bVarsCol, DdNode **pCVars, int nMulti, int *pSimple)
type definitions ///
Definition casDec.c:36
#define assert(ex)
Definition util_old.h:213
char * memset()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteDDintoBLIFfile()

void WriteDDintoBLIFfile ( FILE * pFile,
DdNode * Func,
char * OutputName,
char * Prefix,
char ** InputNames )
extern

BLIF WRITING FUNCTIONS ///.

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 803 of file casCore.c.

810{
811 int i;
812 st__table * visited;
813 st__generator * gen = NULL;
814 long refAddr, diff, mask;
815 DdNode * Node, * Else, * ElseR, * Then;
816
817 /* Initialize symbol table for visited nodes. */
819
820 /* Collect all the nodes of this DD in the symbol table. */
821 cuddCollectNodes( Cudd_Regular(Func), visited );
822
823 /* Find how many most significant hex digits are identical
824 ** in the addresses of all the nodes. Build a mask based
825 ** on this knowledge, so that digits that carry no information
826 ** will not be printed. This is done in two steps.
827 ** 1. We scan the symbol table to find the bits that differ
828 ** in at least 2 addresses.
829 ** 2. We choose one of the possible masks. There are 8 possible
830 ** masks for 32-bit integer, and 16 possible masks for 64-bit
831 ** integers.
832 */
833
834 /* Find the bits that are different. */
835 refAddr = ( long )Cudd_Regular(Func);
836 diff = 0;
837 gen = st__init_gen( visited );
838 while ( st__gen( gen, ( const char ** ) &Node, NULL ) )
839 {
840 diff |= refAddr ^ ( long ) Node;
841 }
842 st__free_gen( gen );
843 gen = NULL;
844
845 /* Choose the mask. */
846 for ( i = 0; ( unsigned ) i < 8 * sizeof( long ); i += 4 )
847 {
848 mask = ( 1 << i ) - 1;
849 if ( diff <= mask )
850 break;
851 }
852
853
854 // write the buffer for the output
855 fprintf( pFile, ".names %s%lx %s\n", Prefix, ( mask & (long)Cudd_Regular(Func) ) / sizeof(DdNode), OutputName );
856 fprintf( pFile, "%s 1\n", (Cudd_IsComplement(Func))? "0": "1" );
857
858
859 gen = st__init_gen( visited );
860 while ( st__gen( gen, ( const char ** ) &Node, NULL ) )
861 {
862 if ( Node->index == CUDD_MAXINDEX )
863 {
864 // write the terminal node
865 fprintf( pFile, ".names %s%lx\n", Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
866 fprintf( pFile, " %s\n", (cuddV(Node) == 0.0)? "0": "1" );
867 continue;
868 }
869
870 Else = cuddE(Node);
871 ElseR = Cudd_Regular(Else);
872 Then = cuddT(Node);
873
874 assert( InputNames[Node->index] );
875 if ( Else == ElseR )
876 { // no inverter
877 fprintf( pFile, ".names %s %s%lx %s%lx %s%lx\n", InputNames[Node->index],
878 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
879 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
880 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
881 fprintf( pFile, "01- 1\n" );
882 fprintf( pFile, "1-1 1\n" );
883 }
884 else
885 { // inverter
886 int * pSlot;
887 fprintf( pFile, ".names %s %s%lx_i %s%lx %s%lx\n", InputNames[Node->index],
888 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
889 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
890 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
891 fprintf( pFile, "01- 1\n" );
892 fprintf( pFile, "1-1 1\n" );
893
894 // if the inverter is written, skip
895 if ( ! st__find( visited, (char *)ElseR, (char ***)&pSlot ) )
896 assert( 0 );
897 if ( *pSlot )
898 continue;
899 *pSlot = 1;
900
901 fprintf( pFile, ".names %s%lx %s%lx_i\n",
902 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
903 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode) );
904 fprintf( pFile, "0 1\n" );
905 }
906 }
907 st__free_gen( gen );
908 gen = NULL;
909 st__free_table( visited );
910}
int st__gen(st__generator *gen, const char **key_p, char **value_p)
Definition st.c:501
int st__ptrhash(const char *, int)
Definition st.c:467
int st__ptrcmp(const char *, const char *)
Definition st.c:479
void st__free_gen(st__generator *gen)
Definition st.c:555
int st__find(st__table *table, char *key, char ***slot)
Definition st.c:264
st__table * st__init_table(st__compare_func_type compare, st__hash_func_type hash)
Definition st.c:72
st__generator * st__init_gen(st__table *table)
Definition st.c:485
void st__free_table(st__table *table)
Definition st.c:81
Definition st.h:52
Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteDDintoBLIFfileReorder()

void WriteDDintoBLIFfileReorder ( DdManager * dd,
FILE * pFile,
DdNode * Func,
char * OutputName,
char * Prefix,
char ** InputNames )
extern

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

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 928 of file casCore.c.

935{
936 int i;
937 st__table * visited;
938 st__generator * gen = NULL;
939 long refAddr, diff, mask;
940 DdNode * Node, * Else, * ElseR, * Then;
941
942
944 DdNode * bFmin;
945 abctime clk1;
946
947 if ( s_ddmin == NULL )
948 s_ddmin = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0);
949
950 clk1 = Abc_Clock();
951 bFmin = Cudd_bddTransfer( dd, s_ddmin, Func ); Cudd_Ref( bFmin );
952
953 // reorder
954 printf( "Nodes before = %d. ", Cudd_DagSize(bFmin) );
955 Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SYMM_SIFT,1);
956// Cudd_ReduceHeap(s_ddmin,CUDD_REORDER_SYMM_SIFT_CONV,1);
957 printf( "Nodes after = %d. \n", Cudd_DagSize(bFmin) );
959
960
961
962 /* Initialize symbol table for visited nodes. */
964
965 /* Collect all the nodes of this DD in the symbol table. */
966 cuddCollectNodes( Cudd_Regular(bFmin), visited );
967
968 /* Find how many most significant hex digits are identical
969 ** in the addresses of all the nodes. Build a mask based
970 ** on this knowledge, so that digits that carry no information
971 ** will not be printed. This is done in two steps.
972 ** 1. We scan the symbol table to find the bits that differ
973 ** in at least 2 addresses.
974 ** 2. We choose one of the possible masks. There are 8 possible
975 ** masks for 32-bit integer, and 16 possible masks for 64-bit
976 ** integers.
977 */
978
979 /* Find the bits that are different. */
980 refAddr = ( long )Cudd_Regular(bFmin);
981 diff = 0;
982 gen = st__init_gen( visited );
983 while ( st__gen( gen, ( const char ** ) &Node, NULL ) )
984 {
985 diff |= refAddr ^ ( long ) Node;
986 }
987 st__free_gen( gen );
988 gen = NULL;
989
990 /* Choose the mask. */
991 for ( i = 0; ( unsigned ) i < 8 * sizeof( long ); i += 4 )
992 {
993 mask = ( 1 << i ) - 1;
994 if ( diff <= mask )
995 break;
996 }
997
998
999 // write the buffer for the output
1000 fprintf( pFile, ".names %s%lx %s\n", Prefix, ( mask & (long)Cudd_Regular(bFmin) ) / sizeof(DdNode), OutputName );
1001 fprintf( pFile, "%s 1\n", (Cudd_IsComplement(bFmin))? "0": "1" );
1002
1003
1004 gen = st__init_gen( visited );
1005 while ( st__gen( gen, ( const char ** ) &Node, NULL ) )
1006 {
1007 if ( Node->index == CUDD_MAXINDEX )
1008 {
1009 // write the terminal node
1010 fprintf( pFile, ".names %s%lx\n", Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
1011 fprintf( pFile, " %s\n", (cuddV(Node) == 0.0)? "0": "1" );
1012 continue;
1013 }
1014
1015 Else = cuddE(Node);
1016 ElseR = Cudd_Regular(Else);
1017 Then = cuddT(Node);
1018
1019 assert( InputNames[Node->index] );
1020 if ( Else == ElseR )
1021 { // no inverter
1022 fprintf( pFile, ".names %s %s%lx %s%lx %s%lx\n", InputNames[Node->index],
1023 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
1024 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
1025 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
1026 fprintf( pFile, "01- 1\n" );
1027 fprintf( pFile, "1-1 1\n" );
1028 }
1029 else
1030 { // inverter
1031 fprintf( pFile, ".names %s %s%lx_i %s%lx %s%lx\n", InputNames[Node->index],
1032 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
1033 Prefix, ( mask & (long)Then ) / sizeof(DdNode),
1034 Prefix, ( mask & (long)Node ) / sizeof(DdNode) );
1035 fprintf( pFile, "01- 1\n" );
1036 fprintf( pFile, "1-1 1\n" );
1037
1038 fprintf( pFile, ".names %s%lx %s%lx_i\n",
1039 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode),
1040 Prefix, ( mask & (long)ElseR ) / sizeof(DdNode) );
1041 fprintf( pFile, "0 1\n" );
1042 }
1043 }
1044 st__free_gen( gen );
1045 gen = NULL;
1046 st__free_table( visited );
1047
1048
1050 Cudd_RecursiveDeref( s_ddmin, bFmin );
1052}
Here is the call graph for this function:

◆ WriteLUTSintoBLIFfile()

void WriteLUTSintoBLIFfile ( FILE * pFile,
DdManager * dd,
LUT ** pLuts,
int nLuts,
DdNode ** bCVars,
char ** pNames,
int nNames,
char * FileName )

static functions ///

Definition at line 416 of file casDec.c.

417{
418 int i, v, o;
419 static char * pNamesLocalIn[MAXINPUTS];
420 static char * pNamesLocalOut[MAXINPUTS];
421 static char Buffer[100];
422 DdNode * bCube, * bCof, * bFunc;
423 LUT * p;
424
425 // go through all the LUTs
426 for ( i = 0; i < nLuts; i++ )
427 {
428 // get the pointer to the LUT
429 p = pLuts[i];
430
431 if ( i == nLuts -1 )
432 {
433 assert( p->nMulti == 1 );
434 }
435
436
437 fprintf( pFile, "#----------------- LUT #%d ----------------------\n", i );
438
439
440 // fill in the names for the current LUT
441
442 // write the outputs of the previous LUT
443 if ( i != 0 )
444 for ( v = 0; v < p->nInsP; v++ )
445 {
446 sprintf( Buffer, "LUT%02d_%02d", i-1, v );
447 pNamesLocalIn[dd->invperm[v]] = Extra_UtilStrsav( Buffer );
448 }
449 // write the primary inputs of the current LUT
450 for ( v = 0; v < p->nIns - p->nInsP; v++ )
451 pNamesLocalIn[dd->invperm[p->Level+v]] = Extra_UtilStrsav( pNames[dd->invperm[p->Level+v]] );
452 // write the outputs of the current LUT
453 for ( v = 0; v < p->nMulti; v++ )
454 {
455 sprintf( Buffer, "LUT%02d_%02d", i, v );
456 if ( i != nLuts - 1 )
457 pNamesLocalOut[v] = Extra_UtilStrsav( Buffer );
458 else
459 pNamesLocalOut[v] = Extra_UtilStrsav( "F" );
460 }
461
462
463 // write LUT outputs
464
465 // get the prefix
466 sprintf( Buffer, "L%02d_", i );
467
468 // get the cube of encoding variables
469 bCube = Extra_bddBitsToCube( dd, (1<<p->nMulti)-1, p->nMulti, bCVars, 1 ); Cudd_Ref( bCube );
470
471 // write each output of the LUT
472 for ( o = 0; o < p->nMulti; o++ )
473 {
474 // get the cofactor of this output
475 bCof = Cudd_Cofactor( dd, p->bRelation, bCVars[o] ); Cudd_Ref( bCof );
476 // quantify the remaining variables to get the function
477 bFunc = Cudd_bddExistAbstract( dd, bCof, bCube ); Cudd_Ref( bFunc );
478 Cudd_RecursiveDeref( dd, bCof );
479
480 // write BLIF
481 sprintf( Buffer, "L%02d_%02d_", i, o );
482
483// WriteDDintoBLIFfileReorder( dd, pFile, bFunc, pNamesLocalOut[o], Buffer, pNamesLocalIn );
484 // does not work well; the advantage is marginal (30%), the run time is huge...
485
486 WriteDDintoBLIFfile( pFile, bFunc, pNamesLocalOut[o], Buffer, pNamesLocalIn );
487 Cudd_RecursiveDeref( dd, bFunc );
488 }
489 Cudd_RecursiveDeref( dd, bCube );
490
491 // clean up the previous local names
492 for ( v = 0; v < dd->size; v++ )
493 {
494 if ( pNamesLocalIn[v] )
495 ABC_FREE( pNamesLocalIn[v] );
496 pNamesLocalIn[v] = NULL;
497 }
498 for ( v = 0; v < p->nMulti; v++ )
499 ABC_FREE( pNamesLocalOut[v] );
500 }
501}
void WriteDDintoBLIFfile(FILE *pFile, DdNode *Func, char *OutputName, char *Prefix, char **InputNames)
BLIF WRITING FUNCTIONS ///.
Definition casCore.c:803
char * Extra_UtilStrsav(const char *s)
char * sprintf()
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ s_EncComputeTime

long s_EncComputeTime

Definition at line 86 of file casDec.c.

◆ s_EncodingTime

long s_EncodingTime

Definition at line 83 of file casDec.c.

◆ s_EncSearchTime

long s_EncSearchTime

Definition at line 85 of file casDec.c.