ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
abcCas.c
Go to the documentation of this file.
1
20
21#include "base/abc/abc.h"
22#include "bool/kit/kit.h"
23#include "aig/miniaig/miniaig.h"
24#include "misc/util/utilTruth.h"
25
26#ifdef ABC_USE_CUDD
27#include "bdd/extrab/extraBdd.h"
28//#include "bdd/extrab/extraLutCas.h"
29#endif
30
32
33
34/*
35 This LUT cascade synthesis algorithm is described in the paper:
36 A. Mishchenko and T. Sasao, "Encoding of Boolean functions and its
37 application to LUT cascade synthesis", Proc. IWLS '02, pp. 115-120.
38 http://www.eecs.berkeley.edu/~alanmi/publications/2002/iwls02_enc.pdf
39*/
40
44
45#ifdef ABC_USE_CUDD
46
47extern int Abc_CascadeExperiment( char * pFileGeneric, DdManager * dd, DdNode ** pOutputs, int nInputs, int nOutputs, int nLutSize, int fCheck, int fVerbose );
48
52
64Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVerbose )
65{
66 DdManager * dd;
67 DdNode ** ppOutputs;
68 Abc_Ntk_t * pNtkNew;
69 Abc_Obj_t * pNode;
70 char * pFileGeneric;
71 int fBddSizeMax = 500000;
72 int i, fReorder = 1;
73 abctime clk = Abc_Clock();
74
75 assert( Abc_NtkIsStrash(pNtk) );
76 // compute the global BDDs
77 if ( Abc_NtkBuildGlobalBdds(pNtk, fBddSizeMax, 1, fReorder, 0, fVerbose) == NULL )
78 return NULL;
79
80 if ( fVerbose )
81 {
82 DdManager * dd = (DdManager *)Abc_NtkGlobalBddMan( pNtk );
83 printf( "Shared BDD size = %6d nodes. ", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
84 ABC_PRT( "BDD construction time", Abc_Clock() - clk );
85 }
86
87 // collect global BDDs
88 dd = (DdManager *)Abc_NtkGlobalBddMan( pNtk );
89 ppOutputs = ABC_ALLOC( DdNode *, Abc_NtkCoNum(pNtk) );
90 Abc_NtkForEachCo( pNtk, pNode, i )
91 ppOutputs[i] = (DdNode *)Abc_ObjGlobalBdd(pNode);
92
93 // call the decomposition
94 pFileGeneric = Extra_FileNameGeneric( pNtk->pSpec );
95 if ( !Abc_CascadeExperiment( pFileGeneric, dd, ppOutputs, Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), nLutSize, fCheck, fVerbose ) )
96 {
97 // the LUT size is too small
98 }
99
100 // for now, duplicate the network
101 pNtkNew = Abc_NtkDup( pNtk );
102
103 // cleanup
104 Abc_NtkFreeGlobalBdds( pNtk, 1 );
105 ABC_FREE( ppOutputs );
106 ABC_FREE( pFileGeneric );
107
108// if ( pNtk->pExdc )
109// pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
110 // make sure that everything is okay
111 if ( !Abc_NtkCheck( pNtkNew ) )
112 {
113 printf( "Abc_NtkCollapse: The network check has failed.\n" );
114 Abc_NtkDelete( pNtkNew );
115 return NULL;
116 }
117 return pNtkNew;
118}
119
131void Abc_LutBddTestPrint( DdManager * dd, Vec_Ptr_t * vNodes, Vec_Wrd_t * vMasks, char ** ppNames, int nNames )
132{
133 DdNode * node; int i, k;
134 Vec_PtrForEachEntry( DdNode *, vNodes, node, i )
135 {
136 if (Cudd_IsConstant(node))
137 printf("ID = %2d value = %d ", (int)node->Id, (int)Cudd_V(node) );
138 else
139 printf("ID = %2d level = %2d index = %2d (%s) cof0 = %2d Cof1 = %2d r = %u ",
140 (int)node->Id, Cudd_ReadPerm(dd, node->index), (int)node->index, ppNames[node->index], (int)Cudd_E(node)->Id, (int)Cudd_T(node)->Id, (int)node->ref);
141 if ( Cudd_ReadPerm(dd, node->index) == 0 ) {
142 printf( "\n" );
143 continue;
144 }
145 word Mask = Vec_WrdEntry(vMasks, (int)node->Id);
146 for ( k = 0; k < nNames; k++ ) {
147 if ( Cudd_ReadPerm(dd, k) >= (int)node->index )
148 continue;
149 int Val = (((Mask >> Abc_Var2Lit(k, 0)) & 1) << 1) | ((Mask >> Abc_Var2Lit(k, 1)) & 1);
150 if ( Val == 1 )
151 printf( "%c%s", '-', ppNames[k] );
152 else if ( Val == 2 )
153 printf( "%c%s", '+', ppNames[k] );
154 else if ( Val == 3 )
155 printf( "**" );
156 else if ( Val == 0 )
157 printf( "??" );
158 }
159 printf( "\n" );
160 }
161}
162
163DdManager * s_ddd = NULL;
164int Abc_LutBddCompare( DdNode ** pp1, DdNode ** pp2 )
165{
166 DdNode * pObj1 = *pp1;
167 DdNode * pObj2 = *pp2;
168 return Cudd_ReadPerm(s_ddd, pObj1->index) - Cudd_ReadPerm(s_ddd, pObj2->index);
169}
170void Abc_LutBddTest( DdManager * dd, DdNode * bFunc, char ** ppNames, int nNames, int nVars )
171{
172 DdGen *gen; DdNode *node;
173 Vec_Ptr_t * vNodes = Vec_PtrAlloc( 100 );
174 Cudd_ForeachNode(dd,bFunc,gen,node)
175 Vec_PtrPush( vNodes, node );
176
177 s_ddd = dd;
178 Vec_PtrSort( vNodes, (int (*)(const void *, const void *))Abc_LutBddCompare );
179 s_ddd = NULL;
180
181 int i, k, f;
182 Vec_Int_t * vLevels = Vec_IntAlloc( Vec_PtrSize(vNodes) );
183 Vec_PtrForEachEntry( DdNode *, vNodes, node, i ) {
184 node->Id = i;
185 Vec_IntPush( vLevels, Cudd_ReadPerm(dd, node->index) );
186 }
187 assert( Vec_IntSize(vLevels) == Vec_PtrSize(vNodes) );
188
189 printf( "Size = %d. Fanins = %d. Vars = %d. Nodes = %d.\n", dd->size, nNames, nVars, Vec_PtrSize(vNodes) );
190 Vec_PtrForEachEntry( DdNode *, vNodes, node, i )
191 {
192 if (Cudd_IsConstant(node))
193 printf("ID = %2d value = %d\n", (int)node->Id, (int)Cudd_V(node) );
194 else
195 printf("ID = %2d level = %2d index = %2d (%s) cof0 = %2d Cof1 = %2d r = %u\n",
196 (int)node->Id, Cudd_ReadPerm(dd, node->index), (int)node->index, ppNames[node->index], (int)Cudd_E(node)->Id, (int)Cudd_T(node)->Id, (int)node->ref);
197 }
198
199 Vec_Wec_t * vCofs = Vec_WecStart( nNames+1 );
200 Vec_WecPush( vCofs, 0, 0 );
201 Vec_PtrForEachEntry( DdNode *, vNodes, node, i ) {
202 if ( Cudd_IsConstant(node) )
203 continue;
204 DdNode * pFans[2] = { Cudd_E(node), Cudd_T(node) };
205 int LevelStart = Vec_IntEntry(vLevels, (int)node->Id);
206 for ( f = 0; f < 2; f++ ) {
207 int Level = Cudd_IsConstant(pFans[f]) ? nNames : Vec_IntEntry(vLevels, (int)pFans[f]->Id);
208 for ( k = LevelStart; k < Level; k++ )
209 Vec_WecPushUnique( vCofs, k+1, pFans[f]->Id );
210 }
211 }
212 Vec_WecPrint( vCofs, 0 );
213
214 assert( nNames < 32 );
215 Vec_Wrd_t * vMasks = Vec_WrdStart( Vec_PtrSize(vNodes) );
216 Vec_Int_t * vLevel; int n, Obj;
217 Vec_WecForEachLevel( vCofs, vLevel, i ) {
218 if ( i == Vec_WecSize(vCofs)-1 )
219 break;
220
221 //printf( "Level %2d : ", i );
222 //Vec_IntPrint( vLevel );
223 printf( "Level %2d : ", i );
224 for ( k = 0; k < nNames; k++ ) {
225 if ( Cudd_ReadPerm(dd, k) >= i )
226 continue;
227 int Counts[2] = {0};
228 for ( f = 0; f < 2; f++ )
229 Vec_IntForEachEntry(vLevel, Obj, n)
230 if ( (Vec_WrdEntry(vMasks, Obj) >> Abc_Var2Lit(k, !f)) & 1 )
231 Counts[f]++;
232 printf( "%s(%d:%d) ", ppNames[k], Counts[0], Counts[1] );
233 }
234 printf( "\n" );
235
236 Vec_IntForEachEntry( vLevel, Obj, n )
237 {
238 DdNode * node = (DdNode *)Vec_PtrEntry( vNodes, Obj );
239 if ( Cudd_IsConstant(node) )
240 continue;
241 DdNode * pFans[2] = { Cudd_E(node), Cudd_T(node) };
242 word * pMask = Vec_WrdEntryP( vMasks, (int)node->Id );
243 int LevelStart = Vec_IntEntry(vLevels, (int)node->Id);
244 assert( LevelStart >= i );
245 if ( LevelStart > i )
246 continue;
247 for ( f = 0; f < 2; f++ ) {
248 int Level = Cudd_IsConstant(pFans[f]) ? nNames : Vec_IntEntry(vLevels, (int)pFans[f]->Id);
249 word * pMaskFan = Vec_WrdEntryP( vMasks, (int)pFans[f]->Id );
250 *pMaskFan |= *pMask | ((word)1 << Abc_Var2Lit((int)node->index, !f));
251 for ( k = LevelStart+1; k < Level; k++ ) {
252 *pMaskFan |= ((word)1 << Abc_Var2Lit(Cudd_ReadInvPerm(dd, k), 0));
253 *pMaskFan |= ((word)1 << Abc_Var2Lit(Cudd_ReadInvPerm(dd, k), 1));
254 }
255 }
256 }
257
258 //Abc_LutBddTestPrint( dd, vNodes, vMasks, ppNames, nNames );
259 }
260
261/*
262 assert( nNames < 32 );
263 Vec_Wrd_t * vMasks = Vec_WrdStart( Count );
264 Vec_PtrForEachEntry( DdNode *, vNodes, node, i ) {
265 if ( Cudd_IsConstant(node) )
266 continue;
267 DdNode * pFans[2] = { Cudd_E(node), Cudd_T(node) };
268 word * pMask = Vec_WrdEntryP( vMasks, (int)node->Id );
269 int LevelStart = Vec_IntEntry(vLevels, (int)node->Id);
270 for ( f = 0; f < 2; f++ ) {
271 int Level = Cudd_IsConstant(pFans[f]) ? nNames : Vec_IntEntry(vLevels, (int)pFans[f]->Id);
272 word * pMaskFan = Vec_WrdEntryP( vMasks, (int)pFans[f]->Id );
273 *pMaskFan |= *pMask | ((word)1 << Abc_Var2Lit((int)node->index, !f));
274 for ( k = LevelStart+1; k < Level; k++ ) {
275 *pMaskFan |= ((word)1 << Abc_Var2Lit(Cudd_ReadInvPerm(dd, k), 0));
276 *pMaskFan |= ((word)1 << Abc_Var2Lit(Cudd_ReadInvPerm(dd, k), 1));
277 }
278 }
279 }
280
281 Vec_PtrForEachEntry( DdNode *, vNodes, node, i )
282 {
283 if (Cudd_IsConstant(node))
284 printf("ID = %2d value = %d ", (int)node->Id, (int)Cudd_V(node) );
285 else
286 printf("ID = %2d level = %2d index = %2d (%s) cof0 = %2d Cof1 = %2d r = %u ",
287 (int)node->Id, Cudd_ReadPerm(dd, node->index), (int)node->index, ppNames[node->index], (int)Cudd_E(node)->Id, (int)Cudd_T(node)->Id, (int)node->ref);
288 if ( Cudd_ReadPerm(dd, node->index) == 0 ) {
289 printf( "\n" );
290 continue;
291 }
292 word Mask = Vec_WrdEntry(vMasks, (int)node->Id);
293 for ( k = 0; k < nNames; k++ ) {
294 if ( Cudd_ReadPerm(dd, k) >= (int)node->index )
295 continue;
296 int Val = (((Mask >> Abc_Var2Lit(k, 0)) & 1) << 1) | ((Mask >> Abc_Var2Lit(k, 1)) & 1);
297 if ( Val == 1 )
298 printf( "%c%s", '-', ppNames[k] );
299 else if ( Val == 2 )
300 printf( "%c%s", '+', ppNames[k] );
301 else if ( Val == 3 )
302 printf( "**" );
303 else if ( Val == 0 )
304 printf( "??" );
305 }
306 printf( "\n" );
307 }
308
309 Vec_Int_t * vLevel; int n, Obj;
310 Vec_WecForEachLevelStart( vCofs, vLevel, i, 1 ) {
311 printf( "Level %2d : ", i );
312 for ( k = 0; k < nNames; k++ ) {
313 if ( Cudd_ReadPerm(dd, k) >= i )
314 continue;
315 int Counts[2] = {0};
316 for ( f = 0; f < 2; f++ )
317 Vec_IntForEachEntry(vLevel, Obj, n)
318 if ( (Vec_WrdEntry(vMasks, Obj) >> Abc_Var2Lit(k, !f)) & 1 )
319 Counts[f]++;
320 printf( "%s(%d:%d) ", ppNames[k], Counts[0], Counts[1] );
321 }
322 printf( "\n" );
323 }
324*/
325
326 Vec_IntFree( vLevels );
327 Vec_WecFree( vCofs );
328 Vec_PtrFree( vNodes );
329 Vec_WrdFree( vMasks );
330}
331
332#else
333
334Abc_Ntk_t * Abc_NtkCascade( Abc_Ntk_t * pNtk, int nLutSize, int fCheck, int fVerbose ) { return NULL; }
335word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int nStages, int nRails, int nIters, int fVerbose ) { return NULL; }
336
337#endif
338
339
340/*
341 The decomposed structure of the LUT cascade is represented as an array of 64-bit integers (words).
342 The first word in the record is the number of LUT info blocks in the record, which follow one by one.
343 Each LUT info block contains the following:
344 - the number of words in this block
345 - the number of fanins
346 - the list of fanins
347 - the variable ID of the output (should be a LUT counter starting with the number of variables)
348 - truth tables (one word for 6 vars or less; more words as needed for more than 6 vars)
349 For a 6-input node, the LUT info block takes 10 words (block size, fanin count, 6 fanins, output ID, truth table).
350 For a 4-input node, the LUT info block takes 8 words (block size, fanin count, 4 fanins, output ID, truth table).
351 If the LUT cascade contains a 6-LUT followed by a 4-LUT, the record contains 1+10+8=19 words.
352*/
353
366{
367 word * pLuts = ABC_CALLOC( word, 20 ); int i;
368 // node count
369 pLuts[0] = 2;
370 // first node
371 pLuts[1+0] = 10;
372 pLuts[1+1] = 6;
373 for ( i = 0; i < 6; i++ )
374 pLuts[1+2+i] = i;
375 pLuts[1+8] = 9;
376 pLuts[1+9] = ABC_CONST(0x8000000000000000);
377 // second node
378 pLuts[11+0] = 8;
379 pLuts[11+1] = 4;
380 for ( i = 0; i < 4; i++ )
381 pLuts[11+2+i] = i ? i + 5 : 9;
382 pLuts[11+6] = 10;
383 pLuts[11+7] = ABC_CONST(0xFFFEFFFEFFFEFFFE);
384 return pLuts;
385}
386char Abc_LutCascadeChar( int iVar, int nVars )
387{
388 if ( iVar < nVars )
389 return 'a'+iVar;
390 return 'A'+(iVar-nVars);
391}
392void Abc_LutCascadePrintLut( word * pLuts, int n, int i, int nLutSize, int nVars )
393{
394 word nIns = pLuts[i+1];
395 word * pIns = pLuts+i+2;
396 word * pT = pLuts+i+2+nIns+1; int k;
397 printf( "LUT%d : ", n );
398 printf( "%c = { ", Abc_LutCascadeChar((int)pIns[nIns], nVars) );
399 for ( k = nLutSize-1; k >= nIns; k-- )
400 printf( " " );
401 for ( k = nIns-1; k >= 0; k-- )
402 printf( "%c ", Abc_LutCascadeChar((int)pIns[k], nVars) );
403 printf( "} " );
404 Abc_TtPrintHexRev( stdout, pT, nIns );
405 printf( "\n" );
406}
407void Abc_LutCascadePrint( word * pLuts, int nLutSize )
408{
409 int n, i, nVars = pLuts[3+pLuts[2]];
410 printf( "The LUT cascade contains %d LUTs:\n", (int)pLuts[0] );
411 for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
412 Abc_LutCascadePrintLut( pLuts, n, i, nLutSize, nVars );
413}
414void Abc_LutCascadeGenOne( Vec_Wrd_t * vRes, int nIns, int * pIns, int Out, word * p )
415{
416 int w, nWords = Abc_TtWordNum(nIns);
417 //int iStart = Vec_WrdSize(vRes);
418 Vec_WrdAddToEntry(vRes, 0, 1);
419 Vec_WrdPush( vRes, 3+nIns+nWords );
420 Vec_WrdPush( vRes, nIns );
421 for ( w = 0; w < nIns; w++ )
422 Vec_WrdPush( vRes, pIns[w] );
423 Vec_WrdPush( vRes, Out );
424 if ( nIns < 6 )
425 Vec_WrdPush( vRes, p ? p[0] : Abc_Tt6Stretch(Abc_Random(0), nIns) );
426 else
427 for ( w = 0; w < nWords; w++ )
428 Vec_WrdPush( vRes, p ? p[w] : Abc_RandomW(0) );
429 //printf("Adding LUT: "); Abc_LutCascadePrintLut( Vec_WrdArray(vRes), 0, iStart );
430}
431word * Abc_LutCascadeGen( int nVars, int nLutSize, int nRails, int nShared )
432{
433 assert( nLutSize - nRails - nShared > 0 );
434 Vec_Wrd_t * vRes = Vec_WrdStart( 1 );
435 Vec_Int_t * vFanins = Vec_IntAlloc( nLutSize );
436 Vec_Int_t * vVars = Vec_IntStartNatural( nVars );
437 Vec_Str_t * vGuide = Vec_StrAlloc( 100 );
438 Abc_Random(1);
439 int i, c = 0, Obj, iVarNext = nVars, iVarPrev = -1;
440 while ( Vec_IntSize(vVars) > nLutSize ) {
441 if ( Vec_WrdSize(vRes) > 1 )
442 for ( i = 0; i < nRails; i++ )
443 Vec_IntPop( vVars );
444 Vec_StrPush( vGuide, '0'+c++ );
445 Vec_IntClear( vFanins );
446 for ( i = 0; i < nShared; i++ ) {
447 int Index = -1;
448 do Index = Abc_Random(0) % Vec_IntSize(vVars);
449 while ( Vec_IntFind(vFanins, Vec_IntEntry(vVars, Index)) >= 0 );
450 Vec_IntPush( vFanins, Vec_IntEntry(vVars, Index) );
451 Vec_StrPush( vGuide, 'A'+Vec_IntEntry(vVars, Index) );
452 }
453 for ( i = 0; i < nLutSize - nRails - nShared; i++ ) {
454 int Index = -1;
455 do Index = Abc_Random(0) % Vec_IntSize(vVars);
456 while ( Vec_IntFind(vFanins, Vec_IntEntry(vVars, Index)) >= 0 );
457 Vec_IntPush( vFanins, Vec_IntEntry(vVars, Index) );
458 Vec_StrPush( vGuide, 'a'+Vec_IntEntry(vVars, Index) );
459 Vec_IntDrop( vVars, Index );
460 }
461 if ( Vec_WrdSize(vRes) == 1 ) {
462 for ( i = 0; i < nRails; i++ ) {
463 int Index = -1;
464 do Index = Abc_Random(0) % Vec_IntSize(vVars);
465 while ( Vec_IntFind(vFanins, Vec_IntEntry(vVars, Index)) >= 0 );
466 Vec_IntPush( vFanins, Vec_IntEntry(vVars, Index) );
467 Vec_StrPush( vGuide, 'a'+Vec_IntEntry(vVars, Index) );
468 Vec_IntDrop( vVars, Index );
469 }
470 }
471 else {
472 assert( iVarPrev > 0 );
473 for ( i = 0; i < nRails; i++ ) {
474 Vec_IntPush( vFanins, iVarPrev+i );
475 Vec_StrPush( vGuide, 'a'+iVarPrev+i );
476 }
477 }
478 iVarPrev = iVarNext;
479 assert( Vec_IntSize(vFanins) == nLutSize );
480 for ( i = 0; i < nRails; i++ ) {
481 Abc_LutCascadeGenOne( vRes, Vec_IntSize(vFanins), Vec_IntArray(vFanins), iVarNext++, NULL );
482 Vec_IntPush( vVars, iVarPrev+i );
483 }
484 }
485 assert( Vec_IntSize(vVars) <= nLutSize );
486 Abc_LutCascadeGenOne( vRes, Vec_IntSize(vVars), Vec_IntArray(vVars), iVarNext, NULL );
487 Vec_StrPush( vGuide, '0'+c++ );
488 Vec_IntForEachEntry( vVars, Obj, i )
489 Vec_StrPush( vGuide, 'a'+Obj );
490 Vec_StrPush( vGuide, '\0' );
491
492 printf( "Generated %d-LUT cascade for a %d-var function with %d rails and %d shared vars (node = %d, level = %d).\n",
493 nLutSize, nVars, nRails, nShared, (int)Vec_WrdEntry(vRes, 0), c );
494 printf( "Structural info: %s\n", Vec_StrArray(vGuide) );
495 Vec_StrFree( vGuide );
496
497 word * pRes = Vec_WrdReleaseArray(vRes);
498 Vec_WrdFree( vRes );
499 return pRes;
500}
501word * Abc_LutCascadeTruth( word * pLuts, int nVars )
502{
503 int nWords = Abc_TtWordNum(nVars);
504 Vec_Wrd_t * vFuncs = Vec_WrdStartTruthTables6( nVars );
505 Vec_WrdFillExtra( vFuncs, nWords*(nVars+pLuts[0]+1), (word)0 );
506 word * pCube = Vec_WrdEntryP( vFuncs, nWords*(nVars+pLuts[0]) );
507 int n, i, m, v, iLastLut = -1;
508 for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
509 {
510 word nIns = pLuts[i+1];
511 word * pIns = pLuts+i+2;
512 word * pT = pLuts+i+2+nIns+1;
513 //assert( pLuts[i] == 3+nIns+Abc_TtWordNum(nIns) );
514 assert( pIns[nIns] < nVars+pLuts[0] );
515 word * pIn[30], * pOut = Vec_WrdEntryP( vFuncs, nWords*pIns[nIns] );
516 for ( v = 0; v < nIns; v++ )
517 pIn[v] = Vec_WrdEntryP( vFuncs, nWords*pIns[v] );
518 for ( m = 0; m < (1<<nIns); m++ ) {
519 if ( !Abc_TtGetBit(pT, m) )
520 continue;
521 Abc_TtFill(pCube, nWords);
522 for ( v = 0; v < nIns; v++ )
523 Abc_TtAndCompl(pCube, pCube, 0, pIn[v], !((m>>v)&1), nWords);
524 Abc_TtOr(pOut, pOut, pCube, nWords);
525 }
526 iLastLut = pIns[nIns];
527 }
528 word * pRes = Vec_WrdReleaseArray(vFuncs);
529 Abc_TtCopy( pRes, pRes + nWords*iLastLut, nWords, 0 );
530 Vec_WrdFree( vFuncs );
531 return pRes;
532}
533void Abc_LutCascadeMinBase( word * pLuts, int nVars )
534{
535 int i, n, v, pFans[32];
536 for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
537 {
538 word nIns = pLuts[i+1];
539 word * pIns = pLuts+i+2;
540 word * pT = pLuts+i+2+nIns+1;
541 assert( pLuts[i] == 3+nIns+Abc_TtWordNum(nIns) );
542 assert( pIns[nIns] < nVars+pLuts[0] );
543 for ( v = 0; v < nIns; v++ )
544 pFans[v] = (int)pIns[v];
545 int nFans = Abc_TtMinBase( pT, pFans, (int)nIns, (int)nIns );
546 pLuts[i+1] = (word)nFans;
547 for ( v = 0; v < nFans; v++ )
548 pIns[v] = (word)pFans[v];
549 pIns[nFans] = pIns[nIns];
550 memcpy( pLuts+i+2+nFans+1, pT, sizeof(word)*Abc_TtWordNum(nFans) );
551 }
552}
554{
555 return (int)pLuts[0];
556}
557word * Abc_LutCascadeTest( Mini_Aig_t * p, int nLutSize, int fVerbose )
558{
559 word * pLuts = Abc_LutCascadeGenTest();
560 Abc_LutCascadePrint( pLuts, nLutSize );
561 return pLuts;
562}
563
564
576
577// computes permutation masks for the current stage
578int Abc_TtGetGuide( char * pGuide, int Iter, Vec_Int_t * vVarIDs, int fShared )
579{
580 int i, Res = 0, Count = 0;
581 for ( i = 0; pGuide[i]; i++ )
582 if ( pGuide[i] >= '0' && pGuide[i] <= '9' ) {
583 if ( Count++ == Iter )
584 break;
585 }
586 assert( i < strlen(pGuide) );
587 assert( pGuide[i] == '0'+Iter );
588 for ( i++; pGuide[i]; i++ )
589 {
590 char Char = pGuide[i];
591 if ( Char >= '0' && Char <= '9' )
592 break;
593 if ( fShared && Char >= 'a' && Char <= 'z' )
594 continue;
595 int Value = -1;
596 if ( Char >= 'a' && Char <= 'z' )
597 Value = Char - 'a';
598 else if ( Char >= 'A' && Char <= 'Z' )
599 Value = Char - 'A';
600 else assert( 0 );
601 int iPlace = Vec_IntFind(vVarIDs, Value);
602 assert( iPlace >= 0 );
603 assert( ((Res >> iPlace) & 1) == 0 );
604 Res |= 1 << iPlace;
605 }
606 return Res;
607}
608
609// moves variables in the mask to be the last ones in the order
610void Abc_TtPermuteMask( word * p, int nVars, int Mask, Vec_Int_t * vPerm )
611{
612 assert( !vPerm || nVars == Vec_IntSize(vPerm) );
613 int v, i, iLast = nVars-1, nWords = Abc_TtWordNum(nVars);
614 int * pPerm = vPerm ? Vec_IntArray(vPerm) : NULL;
615 if ( 0 && vPerm ) {
616 printf( "Beg: " );
617 for ( v = 0; v < nVars; v++ )
618 printf( "%c ", 'a'+Vec_IntEntry(vPerm, v) );
619 printf( "\n" );
620 printf( "Bit: " );
621 for ( v = 0; v < nVars; v++ )
622 printf( "%c ", (Mask >> v) & 1 ? '1' : '-' );
623 printf( "\n" );
624 }
625 for ( v = nVars-1; v >= 0; v-- ) {
626 if ( ((Mask >> v) & 1) == 0 )
627 continue;
628 if ( v == iLast ) {
629 iLast--;
630 continue;
631 }
632 assert( v < iLast );
633 for ( i = v; i < iLast; i++ ) {
634 Abc_TtSwapAdjacent( p, nWords, i );
635 if ( pPerm ) ABC_SWAP( int, pPerm[i], pPerm[i+1] )
636 }
637 iLast--;
638 }
639 if ( 0 && vPerm ) {
640 printf( "End: " );
641 for ( v = 0; v < nVars; v++ )
642 printf( "%c ", 'a'+Vec_IntEntry(vPerm, v) );
643 printf( "\n" );
644 }
645}
646
647
648// checks if the given function exists in storage
649// if the function does not exist, adds it to storage
650// returns the number of the function in storage
651int Abc_LutCascadeLookup( word * pStore, int nFuncs, word * pFunc, int nWords )
652{
653 int i;
654 for ( i = 0; i < nFuncs; i++ )
655 if ( Abc_TtEqual( pStore+i*nWords, pFunc, nWords ) )
656 return i;
657 Abc_TtCopy( pStore+i*nWords, pFunc, nWords, 0 );
658 assert( i == nFuncs );
659 return i;
660}
661void Abc_LutCascadeDerive( word * p, int nVars, int nBVars, int Myu, word * pRem, word * pDec, int nStep )
662{
663 int nFVars = nVars-nBVars; assert( nFVars >= 6 );
664 int nEVars = Abc_Base2Log(Myu);
665 int nFWords = Abc_TtWordNum(nFVars);
666 int m, e, iFunc, nFuncs = 0;
667 //printf( "Decomposition pattern with %d BS vars and %d FS vars: ", nBVars, nFVars );
668 for ( m = 0; m < (1 << nBVars); m++ ) {
669 iFunc = Abc_LutCascadeLookup( pRem, nFuncs, p+m*nFWords, nFWords );
670 //printf( "%x", iFunc );
671 nFuncs = Abc_MaxInt( nFuncs, iFunc+1 );
672 for ( e = 0; e < nEVars; e++ )
673 if ( (iFunc >> e) & 1 )
674 Abc_TtSetBit(pDec+e*nStep, m);
675 }
676 //printf( "\n" );
677 //assert( nFuncs <= Myu );
678 iFunc = nFuncs-1;
679 for ( m = nFuncs; m < (1 << nEVars); m++ )
680 Abc_TtCopy( pRem+m*nFWords, pRem+iFunc*nFWords, nFWords, 0 );
681 if ( nBVars < 6 )
682 for ( e = 0; e < nEVars; e++ )
683 pDec[e*nStep] = Abc_Tt6Stretch( pDec[e*nStep], nBVars );
684}
685
686// performs decomposition of one stage
687static inline int Abc_LutCascadeDecStage( word Guide0, char * pGuide, int Iter, Vec_Wrd_t * vFuncs[3], Vec_Int_t * vVarIDs, int nRVars, int nRails, int nLutSize, int nZParam, int fVerbose, Vec_Wrd_t * vCas, int * pMyu )
688{
689 assert( Vec_IntSize(vVarIDs) > nLutSize );
690 assert( Vec_IntSize(vVarIDs) <= 24 );
691 word Guide = pGuide ? 0 : Guide0;
692 int m, Myu = pGuide ? 1 << nRails : (Guide >> 48) & 0xFF;
693 int nEVars = Abc_Base2Log(Myu);
694 int nVars = Vec_IntSize(vVarIDs);
695 int mBVars = pGuide ? Abc_TtGetGuide(pGuide, Iter, vVarIDs, 0) : Guide & 0xFFFFFF;
696 int nBVars = __builtin_popcount(mBVars);
697 assert( nBVars <= nLutSize );
698 Abc_TtPermuteMask( Vec_WrdArray(vFuncs[0]), nVars, mBVars, vVarIDs );
699 int mSVars = pGuide ? Abc_TtGetGuide(pGuide, Iter, vVarIDs, 1) : (Guide >> 24) & 0xFFFFFF;
700 int nSVars = __builtin_popcount(mSVars);
701 Abc_TtPermuteMask( Vec_WrdArray(vFuncs[0]), nVars, mSVars, vVarIDs );
702 // prepare function (nVars -> nAVars+nVars)
703 int nFVars = nVars - nBVars;
704 int nAVars = nFVars >= 6 ? 0 : 6-nFVars;
705 int nWordsNew = Abc_TtWordNum(nVars+nAVars);
706 Vec_WrdFillExtra( vFuncs[0], nWordsNew, 0 );
707 word * pFunc = Vec_WrdArray(vFuncs[0]);
708 Abc_TtStretch6( pFunc, nVars, nVars+nAVars );
709 Abc_TtPermuteMask( pFunc, nVars+nAVars, (1 << nVars)-1, NULL );
710 // prepare remainder function (nAVars+nFVars+nEVars+nSVars)
711 int nWordsRem = Abc_TtWordNum(nAVars+nFVars+nEVars+nSVars);
712 Vec_WrdFill( vFuncs[1], nWordsRem, 0 );
713 word * pRem = Vec_WrdArray(vFuncs[1]);
714 // prepare decomposed functions (nBVars+nZVars) * nEVars
715 int nUVars = nBVars - nSVars;
716 int nZVars = nUVars >= 6 ? 0 : 6-nUVars;
717 int nWordsDec = Abc_TtWordNum(nBVars+nZVars);
718 int nWordsStep = Abc_TtWordNum(nUVars+nZVars);
719 Vec_WrdFill( vFuncs[2], nWordsDec*nEVars, 0 );
720 word * pDec = Vec_WrdArray(vFuncs[2]);
721 int nSMints = 1 << nSVars;
722 for ( m = 0; m < nSMints; m++ )
723 Abc_LutCascadeDerive(pFunc+m*nWordsNew/nSMints, nVars+nAVars-nSVars, nBVars-nSVars, Myu,
724 pRem+m*nWordsRem/nSMints, pDec+m*nWordsStep, nWordsDec );
725 Abc_TtPermuteMask( pRem, nAVars+nFVars+nEVars+nSVars, (1 << nAVars)-1, NULL );
726 Abc_TtPermuteMask( pRem, nFVars+nEVars+nSVars, ((1 << nEVars)-1) << nFVars, NULL );
727 for ( m = 0; m < nEVars; m++ )
728 Abc_TtPermuteMask( pDec+m*nWordsDec, nUVars+nZVars+nSVars, ((1 << nZVars)-1) << nUVars, NULL );
729 for ( m = 0; m < nEVars; m++ )
730 Abc_LutCascadeGenOne( vCas, nBVars, Vec_IntArray(vVarIDs)+nVars-nBVars, Vec_WrdEntry(vCas,0), pDec+m*nWordsDec );
731 Abc_TtCopy( pFunc, pRem, Abc_TtWordNum(nFVars+nSVars+nEVars), 0 );
732 assert( nEVars < nUVars );
733 for ( m = 0; m < nSVars; m++ )
734 Vec_IntWriteEntry(vVarIDs, nFVars+m, Vec_IntEntry(vVarIDs, nVars-nSVars+m) );
735 for ( m = 0; m < nEVars; m++ )
736 Vec_IntWriteEntry(vVarIDs, nFVars+nSVars+m, Vec_WrdEntry(vCas,0)-nEVars+m );
737 Vec_IntShrink( vVarIDs, nFVars+nSVars+nEVars );
738 return nEVars;
739}
740
743extern void Abc_BSEvalFree( Abc_BSEval_t * p );
744
745word * Abc_LutCascadeDec( Abc_BSEval_t * p, char * pGuide, word * pTruth, int nVarsOrig, Vec_Int_t * vVarIDs, int nRails, int nLutSize, int nStages, int fUseRand, int nZParam, int fXRail, int fVerbose, int * pnStages, int * pMyu )
746{
747 extern Vec_Wrd_t * Abc_TtFindBVarsSVars2( Abc_BSEval_t * p, word * pTruth, int nVars, int nCVars, int nRails, int nLutSize, int fVerbose, int * pMyu, int nMyuIncrease );
748 word * pRes = NULL; int i, nRVars = 0, nVars = Vec_IntSize(vVarIDs);
749 Vec_Wrd_t * vFuncs[3] = { Vec_WrdStart(Abc_TtWordNum(nVars)), Vec_WrdAlloc(0), Vec_WrdAlloc(0) };
750 Abc_TtCopy( Vec_WrdArray(vFuncs[0]), pTruth, Abc_TtWordNum(nVars), 0 );
751 Vec_Wrd_t * vCas = Vec_WrdAlloc( 100 ); Vec_WrdPush( vCas, nVarsOrig );
752 if ( pnStages ) *pnStages = 0;
753 for ( i = 0; Vec_IntSize(vVarIDs) > nLutSize; i++ ) {
754 int nRVarsOld = nRVars;
755 Vec_Wrd_t * vGuides = Abc_TtFindBVarsSVars2( p, Vec_WrdArray(vFuncs[0]), Vec_IntSize(vVarIDs), nRVars, nRails, nLutSize, fVerbose, pMyu, nZParam );
756 if ( vGuides ) {
757 int iEntry = fUseRand ? Abc_Random(0) % Vec_WrdSize(vGuides) : 0;
758 nRVars = Abc_LutCascadeDecStage( Vec_WrdEntry(vGuides, iEntry), pGuide, i, vFuncs, vVarIDs, nRVarsOld, nRails, nLutSize, nZParam, fVerbose, vCas, i ? NULL : pMyu );
759 Vec_WrdFree( vGuides );
760 }
761 else
762 nRVars = -1;
763 if ( i+2 > nStages ) {
764 if ( fVerbose )
765 printf( "The length of the cascade (%d) exceeds the max allowed number of stages (%d).\n", i+2, nStages );
766 nRVars = -1;
767 }
768 if ( fXRail && nRVars == -1 && Vec_IntSize(vVarIDs) > nLutSize-1 ) {
769 Vec_Wrd_t * vGuides = Abc_TtFindBVarsSVars2( p, Vec_WrdArray(vFuncs[0]), Vec_IntSize(vVarIDs), nRVarsOld, nRails+1, nLutSize-1, fVerbose, pMyu, nZParam );
770 if ( vGuides ) {
771 int iEntry = fUseRand ? Abc_Random(0) % Vec_WrdSize(vGuides) : 0;
772 nRVars = Abc_LutCascadeDecStage( Vec_WrdEntry(vGuides, iEntry), pGuide, i, vFuncs, vVarIDs, nRVarsOld, nRails+1, nLutSize-1, nZParam, fVerbose, vCas, NULL );
773 Vec_WrdFree( vGuides );
774 }
775 else
776 nRVars = -1;
777 if ( i+2 > nStages ) {
778 if ( fVerbose )
779 printf( "The length of the cascade (%d) exceeds the max allowed number of stages (%d).\n", i+2, nStages );
780 nRVars = -1;
781 }
782 }
783 if ( nRVars == -1 ) {
784 Vec_IntClear( vVarIDs );
785 if ( fVerbose )
786 printf( "The function is not decomposable with %d rails.\n", nRails );
787 break;
788 }
789 }
790 if ( nRVars != -1 && Vec_IntSize(vVarIDs) > 0 ) {
791 Abc_LutCascadeGenOne( vCas, Vec_IntSize(vVarIDs), Vec_IntArray(vVarIDs), Vec_WrdEntry(vCas, 0), Vec_WrdArray(vFuncs[0]) );
792 Vec_WrdAddToEntry( vCas, 0, -nVarsOrig );
793 pRes = Vec_WrdReleaseArray(vCas);
794 if ( pnStages ) *pnStages = i+1;
795 }
796 Vec_WrdFree( vCas );
797 for ( i = 0; i < 3; i++ )
798 Vec_WrdFree( vFuncs[i] );
799 return pRes;
800}
801
802
814Abc_Obj_t * Abc_NtkLutCascadeDeriveSop( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeNew, word * pT, int nIns, Vec_Int_t * vCover )
815{
816 int RetValue = Kit_TruthIsop( (unsigned *)pT, nIns, vCover, 1 );
817 assert( RetValue == 0 || RetValue == 1 );
818 if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) ) {
819 assert( RetValue == 0 );
820 pNodeNew->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, nIns, NULL );
821 return (Vec_IntSize(vCover) == 0) ? Abc_NtkCreateNodeConst0(pNtkNew) : Abc_NtkCreateNodeConst1(pNtkNew);
822 }
823 else {
824 char * pSop = Abc_SopCreateFromIsop( (Mem_Flex_t *)pNtkNew->pManFunc, nIns, vCover );
825 if ( RetValue ) Abc_SopComplement( (char *)pSop );
826 pNodeNew->pData = pSop;
827 return pNodeNew;
828 }
829}
830Abc_Ntk_t * Abc_NtkLutCascadeFromLuts( word * pLuts, int nVars, Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
831{
832 Abc_Ntk_t * pNtkNew = NULL;
833 Abc_Obj_t * pObj; int Id; char pName[2] = {0};
834 Vec_Ptr_t * vCopy = Vec_PtrStart( nVars + pLuts[0] + 1000 );
835 if ( pNtk ) {
836 pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
837 }
838 else {
839 pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP , 0 );
840 pNtkNew->pName = Extra_UtilStrsav("cas");
841 //pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
842 for ( Id = 0; Id < nVars; Id++ ) {
843 pObj = Abc_NtkCreatePi(pNtkNew);
844 pName[0] = 'a' + Id;
845 Abc_ObjAssignName( pObj, pName, NULL );
846 }
847 pObj = Abc_NtkCreatePo(pNtkNew);
848 Abc_ObjAssignName( pObj, "Out", NULL );
849 }
850 Abc_NtkForEachCi( pNtkNew, pObj, Id )
851 Vec_PtrWriteEntry( vCopy, Id, pObj );
852 Vec_Int_t * vCover = Vec_IntAlloc( 1000 );
853 word n, i, k, iLastLut = -1;
854 for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
855 {
856 word nIns = pLuts[i+1];
857 word * pIns = pLuts+i+2;
858 word * pT = pLuts+i+2+nIns+1;
859 Abc_Obj_t * pNodeNew = Abc_NtkCreateNode( pNtkNew );
860 for ( k = 0; k < nIns; k++ )
861 Abc_ObjAddFanin( pNodeNew, (Abc_Obj_t *)Vec_PtrEntry(vCopy, pIns[k]) );
862 Abc_Obj_t * pObjNew = Abc_NtkLutCascadeDeriveSop( pNtkNew, pNodeNew, pT, nIns, vCover );
863 Vec_PtrWriteEntry( vCopy, pIns[nIns], pObjNew );
864 iLastLut = pIns[nIns];
865 }
866 Vec_IntFree( vCover );
867 assert( Abc_NtkCoNum(pNtkNew) == 1 );
868 Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, 0), (Abc_Obj_t *)Vec_PtrEntry(vCopy, iLastLut) );
869 Vec_PtrFree( vCopy );
870 if ( !Abc_NtkCheck( pNtkNew ) )
871 {
872 printf( "Abc_NtkLutCascadeFromLuts: The network check has failed.\n" );
873 Abc_NtkDelete( pNtkNew );
874 return NULL;
875 }
876 return pNtkNew;
877}
878Abc_Ntk_t * Abc_NtkLutCascade( Abc_Ntk_t * pNtk, int nLutSize, int nStages, int nRails, int nIters, int fVerbose )
879{
880 extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk );
881 extern Mini_Aig_t * Gia_ManToMiniAig( Gia_Man_t * pGia );
882 //extern word * Abc_LutCascade( Mini_Aig_t * p, int nLutSize, int nStages, int nRails, int nIters, int fVerbose );
883 Gia_Man_t * pGia = Abc_NtkStrashToGia( pNtk );
884 Mini_Aig_t * pM = Gia_ManToMiniAig( pGia );
885 //word * pLuts = Abc_LutCascade( pM, nLutSize, nStages, nRails, nIters, fVerbose );
886 word * pLuts = Abc_LutCascadeTest( pM, nLutSize, 0 );
887 Abc_Ntk_t * pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, Abc_NtkCiNum(pNtk), pNtk, nLutSize, fVerbose ) : NULL;
888 ABC_FREE( pLuts );
889 Mini_AigStop( pM );
890 Gia_ManStop( pGia );
891 return pNew;
892}
893Abc_Ntk_t * Abc_NtkLutCascadeOne( Abc_Ntk_t * pNtk, int nLutSize, int nStages, int nRails, int nIters, int nJRatio, int nZParam, int fXRail, int Seed, int fVerbose, int fVeryVerbose, char * pGuide )
894{
895 extern Gia_Man_t * Abc_NtkStrashToGia( Abc_Ntk_t * pNtk );
896 int i, nWords = Abc_TtWordNum(Abc_NtkCiNum(pNtk));
897 word * pCopy = ABC_ALLOC( word, nWords );
898 Gia_Man_t * pGia = Abc_NtkStrashToGia( pNtk );
899 Abc_Ntk_t * pNew = NULL;
900 Abc_Random(1);
901 for ( i = 0; i < Seed; i++ )
902 Abc_Random(0);
904 for ( int Iter = 0; Iter < nIters; Iter++ ) {
905 word * pTruth1 = Gia_ObjComputeTruthTable( pGia, Gia_ManCo(pGia, 0) );
906 Abc_TtCopy( pCopy, pTruth1, nWords, 0 );
907
908 int nVars = -1;
909 Vec_Int_t * vVarIDs = Vec_IntStartNatural( Abc_NtkCiNum(pNtk) );
910 Abc_TtMinimumBase( pTruth1, Vec_IntArray(vVarIDs), Abc_NtkCiNum(pNtk), &nVars );
911 Vec_IntShrink( vVarIDs, nVars );
912 if ( fVerbose ) {
913 printf( "Iter %2d : ", Iter );
914 if ( Abc_NtkCiNum(pNtk) != nVars )
915 printf( "The support of the function is reduced from %d to %d variables.\n", Abc_NtkCiNum(pNtk), nVars );
916 printf( "Decomposing %d-var function into %d-rail cascade of %d-LUTs", nVars, nRails, nLutSize );
917 if ( pGuide )
918 printf( " using structural info: %s", pGuide );
919 printf( ".\n" );
920 }
921
922 word * pLuts = Abc_LutCascadeDec( p, pGuide, pTruth1, Abc_NtkCiNum(pNtk), vVarIDs, nRails, nLutSize, nStages, (int)(Iter >= 0), nZParam, fXRail, fVeryVerbose, NULL, NULL );
923 pNew = pLuts ? Abc_NtkLutCascadeFromLuts( pLuts, Abc_NtkCiNum(pNtk), pNtk, nLutSize, fVerbose ) : NULL;
924 Vec_IntFree( vVarIDs );
925
926 if ( pLuts ) {
927 Abc_LutCascadeMinBase( pLuts, Abc_NtkCiNum(pNtk) );
928 if ( fVerbose )
929 Abc_LutCascadePrint( pLuts, nLutSize );
930 word * pTruth2 = Abc_LutCascadeTruth( pLuts, Abc_NtkCiNum(pNtk) );
931 if ( !Abc_TtEqual(pCopy, pTruth2, nWords) ) {
932 printf( "Verification FAILED.\n" );
933 printf("Function before: "); Abc_TtPrintHexRev( stdout, pCopy, Abc_NtkCiNum(pNtk) ); printf( "\n" );
934 printf("Function after: "); Abc_TtPrintHexRev( stdout, pTruth2, Abc_NtkCiNum(pNtk) ); printf( "\n" );
935 }
936 else if ( fVerbose )
937 printf( "Verification passed.\n" );
938 ABC_FREE( pLuts );
939 ABC_FREE( pTruth2 );
940 break;
941 }
942 //ABC_FREE( pTruth1 );
943 }
944 Abc_BSEvalFree( p );
945 ABC_FREE( pCopy );
946 Gia_ManStop( pGia );
947 return pNew;
948}
949Abc_Ntk_t * Abc_NtkLutCascadeGen( int nLutSize, int nStages, int nRails, int nShared, int fVerbose )
950{
951 int nVars = nStages * nLutSize - (nStages-1) * (nRails + nShared);
952 word * pLuts = Abc_LutCascadeGen( nVars, nLutSize, nRails, nShared );
953 Abc_Ntk_t * pNew = Abc_NtkLutCascadeFromLuts( pLuts, nVars, NULL, nLutSize, fVerbose );
954 Abc_LutCascadePrint( pLuts, nLutSize );
955 if ( fVerbose ) {
956 word * pTruth = Abc_LutCascadeTruth( pLuts, nVars );
957 if ( nVars <= 10 ) {
958 printf( "Function: "); Abc_TtPrintHexRev( stdout, pTruth, nVars ); printf( "\n" );
959 }
960 ABC_FREE( pTruth );
961 }
962 ABC_FREE( pLuts );
963 return pNew;
964}
965
966
978
981{
982 // mapped network
984 // parameters
992 // internal data
994 Vec_Int_t * vTime[2]; // timing info
995 Vec_Int_t * vCrits[2]; // critical terminals
996 Vec_Int_t * vPath[2]; // direct connections
997 Vec_Wec_t * vStack; // processing queue
998 Vec_Int_t * vZeroSlack; // zero-slack nodes
999 Vec_Int_t * vCands; // direct edge candidates
1000 Vec_Int_t * vTrace; // modification trace
1001 Vec_Int_t * vTraceBest; // modification trace
1002};
1003
1004Abc_LutCas_t * Abc_LutCasAlloc( Abc_Ntk_t * pNtk, int nLutsMax, int nIters, int fDelayLut, int fDelayRoute, int fDelayDirect, int fVerbose )
1005{
1007 p->pNtk = pNtk;
1008 p->nLutSize = 6;
1009 p->nLutsMax = nLutsMax;
1010 p->nIters = nIters;
1011 p->fDelayLut = fDelayLut;
1012 p->fDelayRoute = fDelayRoute;
1013 p->fDelayDirect = fDelayDirect;
1014 p->fVerbose = fVerbose;
1015 p->vTime[0] = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
1016 p->vTime[1] = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
1017 p->vCrits[0] = Vec_IntAlloc(1000);
1018 p->vCrits[1] = Vec_IntAlloc(1000);
1019 p->vPath[0] = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
1020 p->vPath[1] = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
1021 p->vStack = Vec_WecStart( Abc_NtkLevel(pNtk) + 1 );
1022 p->vZeroSlack = Vec_IntAlloc( 1000 );
1023 p->vCands = Vec_IntAlloc( 1000 );
1024 p->vTrace = Vec_IntAlloc( 1000 );
1025 p->vTraceBest = Vec_IntAlloc( 1000 );
1026 return p;
1027}
1029{
1030 Vec_IntFree( p->vTime[0] );
1031 Vec_IntFree( p->vTime[1] );
1032 Vec_IntFree( p->vCrits[0] );
1033 Vec_IntFree( p->vCrits[1] );
1034 Vec_IntFree( p->vPath[0] );
1035 Vec_IntFree( p->vPath[1] );
1036 Vec_WecFree( p->vStack );
1037 Vec_IntFree( p->vZeroSlack );
1038 Vec_IntFree( p->vCands );
1039 Vec_IntFree( p->vTrace );
1040 Vec_IntFree( p->vTraceBest );
1041 ABC_FREE( p );
1042}
1043
1044
1057{
1058 if ( !Abc_ObjIsNode(pObj) || !Abc_ObjFaninNum(pObj) )
1059 return 0;
1060 if ( Vec_IntEntry(p->vTime[0], pObj->Id) > 0 )
1061 return Vec_IntEntry(p->vTime[0], pObj->Id);
1062 Abc_Obj_t * pNext; int i, Delay, DelayMax = 0;
1063 Abc_ObjForEachFanin( pObj, pNext, i ) {
1064 Delay = Abc_NtkFindPathTimeD_rec( p, pNext );
1065 Delay += Vec_IntEntry(p->vPath[0], pObj->Id) == pNext->Id ? p->fDelayDirect : p->fDelayRoute;
1066 DelayMax = Abc_MaxInt( DelayMax, Delay + p->fDelayLut );
1067 }
1068 Vec_IntWriteEntry( p->vTime[0], pObj->Id, DelayMax );
1069 return DelayMax;
1070}
1072{
1073 Abc_Obj_t * pObj; int i, Delay, DelayMax = 0;
1074 Vec_IntFill( p->vTime[0], Abc_NtkObjNumMax(p->pNtk), 0 );
1075 Abc_NtkForEachCo( p->pNtk, pObj, i ) {
1076 Delay = Abc_NtkFindPathTimeD_rec( p, Abc_ObjFanin0(pObj) );
1077 DelayMax = Abc_MaxInt( DelayMax, Delay + p->fDelayRoute );
1078 }
1079 Vec_IntClear( p->vCrits[0] );
1080 Abc_NtkForEachCo( p->pNtk, pObj, i )
1081 if ( DelayMax == Vec_IntEntry(p->vTime[0], Abc_ObjFaninId0(pObj)) + p->fDelayRoute )
1082 Vec_IntPush( p->vCrits[0], pObj->Id );
1083 return DelayMax;
1084}
1086{
1087 if ( Abc_ObjIsCo(pObj) )
1088 return 0;
1089 if ( Vec_IntEntry(p->vTime[1], pObj->Id) > 0 )
1090 return Vec_IntEntry(p->vTime[1], pObj->Id) + (Abc_ObjIsNode(pObj) ? p->fDelayLut : 0);
1091 Abc_Obj_t * pNext; int i; float Delay, DelayMax = 0;
1092 Abc_ObjForEachFanout( pObj, pNext, i ) {
1093 Delay = Abc_NtkFindPathTimeR_rec( p, pNext );
1094 Delay += Vec_IntEntry(p->vPath[0], pNext->Id) == pObj->Id ? p->fDelayDirect : p->fDelayRoute;
1095 DelayMax = Abc_MaxInt( DelayMax, Delay );
1096 }
1097 Vec_IntWriteEntry( p->vTime[1], pObj->Id, DelayMax );
1098 return DelayMax + (Abc_ObjIsNode(pObj) ? p->fDelayLut : 0);
1099}
1101{
1102 Abc_Obj_t * pObj; int i; int Delay, DelayMax = 0;
1103 Vec_IntFill( p->vTime[1], Abc_NtkObjNumMax(p->pNtk), 0 );
1104 Abc_NtkForEachCi( p->pNtk, pObj, i ) {
1105 Delay = Abc_NtkFindPathTimeR_rec( p, pObj );
1106 DelayMax = Abc_MaxInt( DelayMax, Delay );
1107 }
1108 Vec_IntClear( p->vCrits[1] );
1109 Abc_NtkForEachCi( p->pNtk, pObj, i )
1110 if ( DelayMax == Vec_IntEntry(p->vTime[1], pObj->Id) )
1111 Vec_IntPush( p->vCrits[1], pObj->Id );
1112 return DelayMax;
1113}
1115{
1116 Abc_Obj_t * pObj, * pFanin; int i, k;
1117 Vec_IntClear( p->vCands );
1118 Abc_NtkForEachNode( p->pNtk, pObj, i ) {
1119 if ( Vec_IntEntry(p->vPath[0], pObj->Id) )
1120 continue;
1121 if ( Vec_IntEntry(p->vTime[0], pObj->Id) + Vec_IntEntry(p->vTime[1], pObj->Id) < p->DelayMax )
1122 continue;
1123 assert( Vec_IntEntry(p->vTime[0], pObj->Id) + Vec_IntEntry(p->vTime[1], pObj->Id == p->DelayMax) );
1124 Abc_ObjForEachFanin( pObj, pFanin, k )
1125 if ( Abc_ObjIsNode(pFanin) && !Vec_IntEntry(p->vPath[1], pFanin->Id) &&
1126 Vec_IntEntry(p->vTime[0], pFanin->Id) + p->fDelayRoute + p->fDelayLut == Vec_IntEntry(p->vTime[0], pObj->Id) )
1127 Vec_IntPushTwo( p->vCands, pObj->Id, pFanin->Id );
1128 }
1129}
1131{
1132 int Delay0 = Abc_NtkFindPathTimeD( p );
1133 int Delay1 = Abc_NtkFindPathTimeR( p );
1134 assert( Delay0 == Delay1 );
1135 p->DelayMax = Delay0;
1137 return Delay0;
1138}
1139
1141{
1142 Abc_Obj_t * pNext; int i; int Delay, DelayMax = 0;
1143 Abc_ObjForEachFanin( pObj, pNext, i ) {
1144 Delay = Vec_IntEntry( p->vTime[0], pNext->Id );
1145 Delay += Vec_IntEntry(p->vPath[0], pObj->Id) == pNext->Id ? p->fDelayDirect : p->fDelayRoute;
1146 DelayMax = Abc_MaxInt( DelayMax, Delay + p->fDelayLut );
1147 }
1148 int DelayOld = Vec_IntEntry( p->vTime[0], pObj->Id );
1149 Vec_IntWriteEntry( p->vTime[0], pObj->Id, DelayMax );
1150 assert( DelayOld >= DelayMax );
1151 return DelayOld > DelayMax;
1152}
1154{
1155 Abc_Obj_t * pNext; int i; float Delay, DelayMax = 0;
1156 Abc_ObjForEachFanout( pObj, pNext, i ) {
1157 Delay = Vec_IntEntry(p->vTime[1], pNext->Id) + (Abc_ObjIsNode(pNext) ? p->fDelayLut : 0);
1158 Delay += Vec_IntEntry(p->vPath[0], pNext->Id) == pObj->Id ? p->fDelayDirect : p->fDelayRoute;
1159 DelayMax = Abc_MaxInt( DelayMax, Delay );
1160 }
1161 int DelayOld = Vec_IntEntry( p->vTime[1], pObj->Id );
1162 Vec_IntWriteEntry( p->vTime[1], pObj->Id, DelayMax );
1163 assert( DelayOld >= DelayMax );
1164 return DelayOld > DelayMax;
1165}
1166int Abc_NtkUpdateTiming( Abc_LutCas_t * p, int Node, int Fanin )
1167{
1168 Abc_Obj_t * pNode = Abc_NtkObj( p->pNtk, Node );
1169 Abc_Obj_t * pFanin = Abc_NtkObj( p->pNtk, Fanin );
1170 Abc_Obj_t * pNext, * pTemp; Vec_Int_t * vLevel; int i, k, j;
1171 assert( Abc_ObjIsNode(pNode) && Abc_ObjIsNode(pFanin) );
1172 Vec_WecForEachLevel( p->vStack, vLevel, i )
1173 Vec_IntClear( vLevel );
1174 Abc_NtkIncrementTravId( p->pNtk );
1175 Abc_NodeSetTravIdCurrentId( p->pNtk, Node );
1176 Abc_NodeSetTravIdCurrentId( p->pNtk, Fanin );
1177 Vec_WecPush( p->vStack, pNode->Level, Node );
1178 Vec_WecPush( p->vStack, pFanin->Level, Fanin );
1179 Vec_WecForEachLevelStart( p->vStack, vLevel, i, pNode->Level )
1180 Abc_NtkForEachObjVec( vLevel, p->pNtk, pTemp, k ) {
1181 if ( !Abc_NtkUpdateNodeD(p, pTemp) )
1182 continue;
1183 Abc_ObjForEachFanout( pTemp, pNext, j ) {
1184 if ( Abc_NodeIsTravIdCurrent(pNext) || Abc_ObjIsCo(pNext) )
1185 continue;
1186 Abc_NodeSetTravIdCurrent( pNext );
1187 Vec_WecPush( p->vStack, pNext->Level, pNext->Id );
1188 }
1189 }
1190 Vec_WecForEachLevelReverseStartStop( p->vStack, vLevel, i, pFanin->Level+1, 0 )
1191 Abc_NtkForEachObjVec( vLevel, p->pNtk, pTemp, k ) {
1192 if ( !Abc_NtkUpdateNodeR(p, pTemp) )
1193 continue;
1194 Abc_ObjForEachFanin( pTemp, pNext, j ) {
1195 if ( Abc_NodeIsTravIdCurrent(pNext) )
1196 continue;
1197 Abc_NodeSetTravIdCurrent( pNext );
1198 Vec_WecPush( p->vStack, pNext->Level, pNext->Id );
1199 }
1200 }
1201 j = 0;
1202 Abc_NtkForEachObjVec( p->vCrits[0], p->pNtk, pTemp, i )
1203 if ( Vec_IntEntry(p->vTime[0], Abc_ObjFaninId0(pTemp)) + p->fDelayRoute == p->DelayMax )
1204 Vec_IntWriteEntry( p->vCrits[0], j++, pTemp->Id );
1205 Vec_IntShrink( p->vCrits[0], j );
1206 j = 0;
1207 Abc_NtkForEachObjVec( p->vCrits[1], p->pNtk, pTemp, i )
1208 if ( Vec_IntEntry(p->vTime[1], pTemp->Id) == p->DelayMax )
1209 Vec_IntWriteEntry( p->vCrits[1], j++, pTemp->Id );
1210 Vec_IntShrink( p->vCrits[1], j );
1211 if ( Vec_IntSize(p->vCrits[0]) && Vec_IntSize(p->vCrits[1]) ) {
1212 int j = 0, Node2, Fanin2;
1213 Vec_IntForEachEntryDouble( p->vCands, Node2, Fanin2, i )
1214 if ( !Vec_IntEntry(p->vPath[0], Node2) && !Vec_IntEntry(p->vPath[1], Fanin2) &&
1215 Vec_IntEntry(p->vTime[0], Node2) + Vec_IntEntry(p->vTime[1], Node2) == p->DelayMax &&
1216 Vec_IntEntry(p->vTime[0], Fanin2) + p->fDelayRoute + p->fDelayLut == Vec_IntEntry(p->vTime[0], Node2) )
1217 Vec_IntWriteEntry( p->vCands, j++, Node2 ), Vec_IntWriteEntry( p->vCands, j++, Fanin2 );
1218 Vec_IntShrink( p->vCands, j );
1219 return p->DelayMax;
1220 }
1221 int DelayOld = p->DelayMax;
1223 assert( DelayOld > p->DelayMax );
1224 return p->DelayMax;
1225}
1226
1239{
1240 int nEdgesMax = 10000;
1241 Vec_IntClear( p->vTrace );
1242 Vec_IntFill( p->vPath[0], Vec_IntSize(p->vPath[0]), 0 );
1243 Vec_IntFill( p->vPath[1], Vec_IntSize(p->vPath[1]), 0 );
1245 if ( p->fVerbose )
1246 printf( "Start : %d\n", p->DelayMax );
1247 int i, LastChange = 0;
1248 for ( i = 0; i < nEdgesMax; i++ )
1249 {
1250 float DelayPrev = p->DelayMax;
1251 if ( Vec_IntSize(p->vCands) == 0 )
1252 break;
1253 int Index = rand() % Vec_IntSize(p->vCands)/2;
1254 int Node = Vec_IntEntry( p->vCands, 2*Index );
1255 int Fanin = Vec_IntEntry( p->vCands, 2*Index+1 );
1256 assert( Vec_IntEntry( p->vPath[0], Node ) == 0 );
1257 Vec_IntWriteEntry( p->vPath[0], Node, Fanin );
1258 assert( Vec_IntEntry( p->vPath[1], Fanin ) == 0 );
1259 Vec_IntWriteEntry( p->vPath[1], Fanin, Node );
1260 Vec_IntPushTwo( p->vTrace, Node, Fanin );
1261 //Abc_NtkFindTiming( p );
1262 Abc_NtkUpdateTiming( p, Node, Fanin );
1263 assert( DelayPrev >= p->DelayMax );
1264 if ( DelayPrev > p->DelayMax )
1265 LastChange = i+1;
1266 DelayPrev = p->DelayMax;
1267 if ( p->fVerbose )
1268 printf( "%5d : %d : %4d -> %4d\n", i, p->DelayMax, Fanin, Node );
1269 }
1270 Vec_IntShrink( p->vTrace, 2*LastChange );
1271 return p->DelayMax;
1272}
1274{
1275 Vec_Wec_t * vCasc = Vec_WecAlloc( 100 );
1276 Vec_Int_t * vMap = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
1277 Vec_Int_t * vPath = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
1278 Vec_Int_t * vCounts = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
1279 Abc_Obj_t * pObj; int i, Node, Fanin, Count, nCascs = 0;
1280 Vec_IntForEachEntryDouble( vTrace, Node, Fanin, i ) {
1281 assert( Vec_IntEntry(vPath, Node) == 0 );
1282 Vec_IntWriteEntry( vPath, Node, Fanin );
1283 Vec_IntWriteEntry( vMap, Fanin, 1 );
1284 }
1285 Abc_NtkForEachNode( pNtk, pObj, i ) {
1286 if ( Vec_IntEntry(vMap, pObj->Id) )
1287 continue;
1288 if ( Vec_IntEntry(vPath, pObj->Id) == 0 )
1289 continue;
1290 Vec_Int_t * vLevel = Vec_WecPushLevel( vCasc );
1291 Node = pObj->Id;
1292 Vec_IntPush( vLevel, Node );
1293 while ( (Node = Vec_IntEntry(vPath, Node)) )
1294 Vec_IntPush( vLevel, Node );
1295 Vec_IntAddToEntry( vCounts, Vec_IntSize(vLevel), 1 );
1296 }
1297 printf( "Cascades: " );
1298 Vec_IntForEachEntry( vCounts, Count, i )
1299 if ( Count )
1300 printf( "%d=%d ", i, Count ), nCascs += Count;
1301 printf( "\n" );
1302 Vec_IntFree( vMap );
1303 Vec_IntFree( vPath );
1304 Vec_IntFree( vCounts );
1305 return vCasc;
1306}
1307void Abc_LutCasAssignNames( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, Vec_Wec_t * vCascs )
1308{
1309 Abc_Obj_t * pObj; Vec_Int_t * vLevel; int i, k; char pName[100];
1310 Vec_Int_t * vMap = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
1311 Abc_NtkForEachCo( pNtkNew, pObj, i )
1312 Vec_IntWriteEntry( vMap, Abc_ObjFaninId0(pObj), pObj->Id );
1313 Vec_WecForEachLevel( vCascs, vLevel, i ) {
1314 Abc_NtkForEachObjVec( vLevel, pNtk, pObj, k ) {
1315 assert( Abc_ObjIsNode(pObj) );
1316 sprintf( pName, "c%d_n%d", i, k );
1317 if ( Vec_IntEntry(vMap, pObj->pCopy->Id) == 0 )
1318 Abc_ObjAssignName( Abc_NtkObj(pNtkNew, pObj->pCopy->Id), pName, NULL );
1319 else {
1320 Nm_ManDeleteIdName( pNtkNew->pManName, Vec_IntEntry(vMap, pObj->pCopy->Id) );
1321 Abc_ObjAssignName( Abc_NtkObj(pNtkNew, Vec_IntEntry(vMap, pObj->pCopy->Id)), pName, NULL );
1322 }
1323 }
1324 }
1325 Vec_IntFree( vMap );
1326}
1327void Abc_NtkLutCascadeDumpResults( char * pDumpFile, char * pTest, int Nodes, int Edges, int Levs, int DelStart, int DelStop, float DelRatio, int EdgesUsed, float EdgeRatio, int Cascs, float AveLength, abctime time )
1328{
1329 FILE * pTable = fopen( pDumpFile, "a+" );
1330 fprintf( pTable, "%s,", pTest+28 );
1331 fprintf( pTable, "%d,", Nodes );
1332 fprintf( pTable, "%d,", Edges );
1333 fprintf( pTable, "%d,", Levs );
1334 fprintf( pTable, "%d,", DelStart );
1335 fprintf( pTable, "%d,", DelStop );
1336 fprintf( pTable, "%.2f,", DelRatio );
1337 fprintf( pTable, "%d,", EdgesUsed );
1338 fprintf( pTable, "%.2f,", EdgeRatio );
1339 fprintf( pTable, "%d,", Cascs );
1340 fprintf( pTable, "%.1f,", AveLength );
1341 fprintf( pTable, "%.2f,", 1.0*((double)(time))/((double)CLOCKS_PER_SEC) );
1342 fprintf( pTable, "\n" );
1343 fclose( pTable );
1344}
1345
1346Abc_Ntk_t * Abc_NtkLutCascadeMap( Abc_Ntk_t * pNtk, int nLutsMax, int nIters, int fDelayLut, int fDelayRoute, int fDelayDirect, int fVerbose )
1347{
1348 abctime clk = Abc_Clock();
1349 Abc_Ntk_t * pNtkNew = NULL;
1350 Abc_LutCas_t * p = Abc_LutCasAlloc( pNtk, nLutsMax, nIters, fDelayLut, fDelayRoute, fDelayDirect, fVerbose );
1351 int i, IterBest = 0, DelayStart = Abc_NtkFindTiming( p ), DelayBest = DelayStart, nEdges = Abc_NtkGetTotalFanins(pNtk);
1352 //printf( "Delays: LUT (%d) Route (%d) Direct (%d). Iters = %d. LUTs = %d.\n", fDelayLut, fDelayRoute, fDelayDirect, nIters, Abc_NtkNodeNum(pNtk) );
1353 Vec_IntFill( p->vTraceBest, Abc_NtkNodeNum(pNtk), 0 );
1354 for ( i = 0; i < nIters; i++ )
1355 {
1356 if ( fVerbose )
1357 printf( "ITERATION %2d:\n", i );
1358 float Delay = Abc_NtkAddEdges( p );
1359 if ( DelayBest < Delay || (DelayBest == Delay && Vec_IntSize(p->vTraceBest) <= Vec_IntSize(p->vTrace)) )
1360 continue;
1361 IterBest = i;
1362 DelayBest = Delay;
1363 ABC_SWAP( Vec_Int_t *, p->vTrace, p->vTraceBest );
1364 }
1365 printf( "Delay reduction %d -> %d (-%.2f %%) is found after iter %d with %d edges (%.2f %%). ",
1366 DelayStart, DelayBest, 100.0*(DelayStart - DelayBest)/DelayStart, IterBest, Vec_IntSize(p->vTraceBest)/2, 50.0*Vec_IntSize(p->vTraceBest)/nEdges );
1367 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
1368 Vec_Wec_t * vCascs = Abc_NtkProfileCascades( p->pNtk, p->vTraceBest );
1369// Abc_NtkLutCascadeDumpResults( "stats.csv", pNtk->pName, Abc_NtkNodeNum(pNtk), nEdges, Abc_NtkLevel(pNtk), DelayStart, DelayBest, 100.0*(DelayStart - DelayBest)/DelayStart,
1370// Vec_IntSize(p->vTraceBest)/2, 50.0*Vec_IntSize(p->vTraceBest)/nEdges, Vec_WecSize(vCascs), 0.5*Vec_IntSize(p->vTraceBest)/Abc_MaxInt(1, Vec_WecSize(vCascs)), Abc_Clock() - clk );
1371 Abc_LutCasFree( p );
1372 pNtkNew = Abc_NtkDup( pNtk );
1373 Abc_LutCasAssignNames( pNtk, pNtkNew, vCascs );
1374 Vec_WecFree( vCascs );
1375 return pNtkNew;
1376}
1377
1378
1390Vec_Wrd_t * Abc_NtkLutCasReadTruths( char * pFileName, int nVarsOrig )
1391{
1392 Vec_Wrd_t * vTruths = NULL;
1393 int nWords = Abc_TtWordNum(nVarsOrig);
1394 int nFileSize = Gia_FileSize( pFileName );
1395 FILE * pFile = fopen( pFileName, "rb" );
1396 if ( pFile == NULL ) { printf("Cannot open file \"%s\" for reading.\n", pFileName); return NULL; }
1397 word * pTruth = ABC_ALLOC( word, 2*nWords );
1398 char * pToken, * pLine = ABC_ALLOC( char, nFileSize );
1399 for ( int i = 0; fgets(pLine, nFileSize, pFile); i++ ) {
1400 pToken = strtok(pLine, " ,\n\r\r");
1401 if ( pToken == NULL )
1402 continue;
1403 if ( pToken[0] == '0' && pToken[1] == 'x' )
1404 pToken += 2;
1405 if ( strlen(pToken) != (1 << (nVarsOrig-2)) ) {
1406 printf( "Line %d has truth table of size %d while expected size is %d.\n", i, (int)strlen(pToken), 1 << (nVarsOrig-2) );
1407 Vec_WrdFreeP( &vTruths );
1408 break;
1409 }
1410 if ( !Abc_TtReadHex( pTruth, pToken ) ) {
1411 printf( "Line %d has truth table that cannot be read correctly (%s).\n", i, pToken );
1412 Vec_WrdFreeP( &vTruths );
1413 break;
1414 }
1415 if ( vTruths == NULL )
1416 vTruths = Vec_WrdAlloc( 10000 );
1417 for ( int w = 0; w < nWords; w++ )
1418 Vec_WrdPush( vTruths, pTruth[w] );
1419 }
1420 ABC_FREE( pTruth );
1421 ABC_FREE( pLine );
1422 fclose( pFile );
1423 return vTruths;
1424}
1425
1437void Abc_NtkLutCascadeFile( char * pFileName, int nVarsOrig, int nLutSize, int nStages, int nRails, int nIters, int nJRatio, int nZParam, int Seed, int fVerbose, int fVeryVerbose, int fPrintMyu, int fPrintLev, int fXRail )
1438{
1439 abctime clkStart = Abc_Clock();
1440 int i, nErrors = 0, Sum = 0, nStageCount = 0, MyuMin = 0, nTotalLuts = 0, nWords = Abc_TtWordNum(nVarsOrig);
1441 Vec_Wrd_t * vTruths = NULL;
1442 if ( strstr(pFileName, ".txt") )
1443 vTruths = Abc_NtkLutCasReadTruths( pFileName, nVarsOrig );
1444 else
1445 vTruths = Vec_WrdReadBin( pFileName, 0 );
1446 if ( vTruths == NULL )
1447 return;
1448
1449 int nFuncs = Vec_WrdSize(vTruths)/nWords;
1450 if ( Vec_WrdSize(vTruths) != nFuncs * nWords ) {
1451 printf( "The files size (%d bytes) does not match the truth table size (%d) for the given number of functions (%d).\n", 8*Vec_WrdSize(vTruths), 8*nWords, nFuncs );
1452 Vec_WrdFree( vTruths );
1453 return;
1454 }
1455
1456 Abc_Random(1);
1457 for ( i = 0; i < Seed; i++ )
1458 Abc_Random(0);
1459 printf( "Considering %d functions having %d variables from file \"%s\".\n", nFuncs, nVarsOrig, pFileName );
1460 word * pCopy = ABC_ALLOC( word, nWords );
1461 int Iter = 0, IterReal = 0, LutStats[50] = {0}, StageStats[50] = {0}, MyuStats[50] = {0};
1463 for ( i = 0; i < nFuncs; i++ )
1464 {
1465 word * pTruth = Vec_WrdEntryP( vTruths, i*nWords );
1466 Abc_TtCopy( pCopy, pTruth, nWords, 0 );
1467
1468 if ( fVeryVerbose )
1469 printf( "\n" );
1470 if ( fVerbose || fVeryVerbose )
1471 printf( "Function %4d : ", i );
1472 if ( fVeryVerbose )
1473 Abc_TtPrintHexRev( stdout, pTruth, nVarsOrig ), printf( "\n" );
1474 //continue;
1475
1476 int nVars = -1;
1477 Vec_Int_t * vVarIDs = Vec_IntStartNatural( nVarsOrig );
1478 Abc_TtMinimumBase( pTruth, Vec_IntArray(vVarIDs), nVarsOrig, &nVars );
1479 Vec_IntShrink( vVarIDs, nVars );
1480 if ( fVeryVerbose ) {
1481 if ( nVarsOrig != nVars )
1482 printf( "The support of the function is reduced from %d to %d variables.\n", nVarsOrig, nVars );
1483 printf( "Decomposing %d-var function into %d-rail cascade of %d-LUTs.\n", nVars, nRails, nLutSize );
1484 }
1485
1486 word * pLuts = Abc_LutCascadeDec( p, NULL, pTruth, nVarsOrig, vVarIDs, nRails, nLutSize, nStages, (int)(Iter >= 0), nZParam, fXRail, fVeryVerbose, &nStageCount, &MyuMin );
1487 Vec_IntFree( vVarIDs );
1488 if ( MyuMin < 50 ) MyuStats[MyuMin]++, IterReal++;
1489 if ( pLuts == NULL ) {
1490 if ( ++Iter < nIters ) {
1491 i--;
1492 continue;
1493 }
1494 Iter = 0;
1495 if ( fVerbose || fVeryVerbose )
1496 printf( "Not decomposable.\n" );
1497 continue;
1498 }
1499 Iter = 0;
1500 Sum++;
1501 nTotalLuts += Abc_LutCascadeCount(pLuts);
1502 if ( Abc_LutCascadeCount(pLuts) < 50 )
1503 LutStats[Abc_LutCascadeCount(pLuts)]++;
1504 if ( nStageCount < 50) StageStats[nStageCount]++;
1505 Abc_LutCascadeMinBase( pLuts, nVarsOrig );
1506 word * pTruth2 = Abc_LutCascadeTruth( pLuts, nVarsOrig );
1507 if ( fVeryVerbose )
1508 Abc_LutCascadePrint( pLuts, nLutSize );
1509 if ( fVerbose || fVeryVerbose )
1510 printf( "Decomposition exists. " );
1511 if ( !Abc_TtEqual(pCopy, pTruth2, nWords) ) {
1512 if ( fVerbose || fVeryVerbose ) printf( "Verification FAILED for function %d.\n", i );
1513 if ( fVerbose || fVeryVerbose ) { printf( "Before: " ); Abc_TtPrintHexRev( stdout, pCopy, nVarsOrig ), printf( "\n" ); }
1514 if ( fVerbose || fVeryVerbose ) { printf( "After: " ); Abc_TtPrintHexRev( stdout, pTruth2, nVarsOrig ), printf( "\n" ); }
1515 nErrors++;
1516 }
1517 else if ( fVerbose || fVeryVerbose )
1518 printf( "Verification passed.\n" );
1519 ABC_FREE( pTruth2 );
1520 ABC_FREE( pLuts );
1521 }
1522 Abc_BSEvalFree( p );
1523 ABC_FREE( pCopy );
1524 Vec_WrdFree( vTruths );
1525 if ( fPrintMyu ) {
1526 printf( "Column multiplicity statistics for %d-rail LUT cascade:\n", nRails );
1527 for ( i = 0; i < 50; i++ )
1528 if ( MyuStats[i] )
1529 printf( " %2d Myu : Function count = %8d (%6.2f %%)\n", i, MyuStats[i], 100.0*MyuStats[i]/Abc_MaxInt(1, nFuncs)/IterReal );
1530 }
1531 if ( fPrintLev ) {
1532 printf( "Level count statistics for %d-rail LUT cascade:\n", nRails );
1533 for ( i = 0; i < 50; i++ )
1534 if ( StageStats[i] )
1535 printf( " %2d level : Function count = %8d (%6.2f %%)\n", i, StageStats[i], 100.0*StageStats[i]/Abc_MaxInt(1, nFuncs) );
1536 }
1537 printf( "LUT count statistics for %d-rail LUT cascade:\n", nRails );
1538 for ( i = 0; i < 50; i++ )
1539 if ( LutStats[i] )
1540 printf( " %2d LUT%d : Function count = %8d (%6.2f %%)\n", i, nLutSize, LutStats[i], 100.0*LutStats[i]/Abc_MaxInt(1, nFuncs) );
1541 printf( "Non-decomp : Function count = %8d (%6.2f %%)\n", nFuncs-Sum, 100.0*(nFuncs-Sum)/Abc_MaxInt(1, nFuncs) );
1542 if ( nErrors ) printf( "Verification ***FAILED*** for %d functions (%6.2f %%)\n", nErrors, 100.0*nErrors/Abc_MaxInt(1, nFuncs) );
1543 printf( "Finished %d functions (%.2f LUTs / function; %.2f functions / sec). ",
1544 nFuncs, 1.0*nTotalLuts/Sum, 1.0*nFuncs/(((double)(Abc_Clock() - clkStart))/((double)CLOCKS_PER_SEC)) );
1545 Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
1546}
1547
1559void Vec_WrdWriteTruthHex( char * pFileName, Vec_Wrd_t * vTruths, int nVars )
1560{
1561 FILE * pFile = fopen( pFileName, "wb" );
1562 if ( pFile == NULL ) { printf("Cannot open file \"%s\" for reading.\n", pFileName); return; }
1563 int i, nWords = Abc_TtWordNum(nVars), nFuncs = Vec_WrdSize(vTruths)/nWords;
1564 assert( nFuncs * nWords == Vec_WrdSize(vTruths) );
1565 for ( i = 0; i < nFuncs; i++ )
1566 Abc_TtPrintHexRev( pFile, Vec_WrdEntryP(vTruths, i*nWords), nVars ), fprintf( pFile, "\n" );
1567 fclose( pFile );
1568}
1569void Abc_NtkSuppMinFile( char * pFileName )
1570{
1571 int fError = 0, nFileSize = Gia_FileSize( pFileName );
1572 FILE * pFile = fopen( pFileName, "rb" );
1573 if ( pFile == NULL ) { printf("Cannot open file \"%s\" for reading.\n", pFileName); return; }
1574 Vec_Wrd_t ** pvTruths = ABC_CALLOC( Vec_Wrd_t *, 32 );
1575 char * pToken, * pLine = ABC_ALLOC( char, nFileSize );
1576 word * pTruth = ABC_ALLOC( word, nFileSize/16 );
1577 int Len, nVars = -1, nWords = -1, nFuncs = 0, nSuppSums[2] = {0};
1578 for ( int i = 0; fgets(pLine, nFileSize, pFile); i++ ) {
1579 pToken = strtok(pLine, " ,\n\r\r");
1580 if ( pToken == NULL )
1581 continue;
1582 if ( pToken[0] == '0' && pToken[1] == 'x' )
1583 pToken += 2;
1584 Len = strlen(pToken);
1585 nVars = Abc_Base2Log(Len);
1586 if ( Len != (1 << nVars) ) {
1587 printf( "The number of hex characters (%d) in the truth table listed in line %d is not a degree of 2.\n", Len, i );
1588 fError = 1;
1589 break;
1590 }
1591 nVars += 2;
1592 if ( !Abc_TtReadHex( pTruth, pToken ) ) {
1593 printf( "Line %d has truth table that cannot be read correctly (%s).\n", i, pToken );
1594 fError = 1;
1595 break;
1596 }
1597 nSuppSums[0] += nVars;
1598 Abc_TtMinimumBase( pTruth, NULL, nVars, &nVars );
1599 nSuppSums[1] += nVars;
1600 if ( pvTruths[nVars] == NULL )
1601 pvTruths[nVars] = Vec_WrdAlloc( 10000 );
1602 nWords = Abc_TtWordNum(nVars);
1603 for ( int w = 0; w < nWords; w++ )
1604 Vec_WrdPush( pvTruths[nVars], pTruth[w] );
1605 nFuncs++;
1606 }
1607 ABC_FREE( pTruth );
1608 ABC_FREE( pLine );
1609 fclose( pFile );
1610 if ( fError ) {
1611 for ( nVars = 0; nVars < 32; nVars++ )
1612 if ( pvTruths[nVars] )
1613 Vec_WrdFreeP( &pvTruths[nVars] );
1614 ABC_FREE( pvTruths );
1615 return;
1616 }
1617 // dump the resulting truth tables
1618 printf( "Read and support-minimized %d functions. Total support reduction %d -> %d (%.2f %%).\n",
1619 nFuncs, nSuppSums[0], nSuppSums[1], 100.0*(nSuppSums[0]-nSuppSums[1])/Abc_MaxInt(nSuppSums[0], 1) );
1620 printf( "The resulting function statistics:\n" );
1621 for ( nVars = 0; nVars < 32; nVars++ ) {
1622 if ( pvTruths[nVars] == NULL )
1623 continue;
1624 char pFileName2[1000];
1625 sprintf( pFileName2, "%s_%02d.txt", Extra_FileNameGeneric(pFileName), nVars );
1626 Vec_WrdWriteTruthHex( pFileName2, pvTruths[nVars], nVars );
1627 printf( "Support size %2d : Dumped %6d truth tables into file \"%s\".\n",
1628 nVars, Vec_WrdSize(pvTruths[nVars])/Abc_TtWordNum(nVars), pFileName2 );
1629 Vec_WrdFreeP( &pvTruths[nVars] );
1630 }
1631 ABC_FREE( pvTruths );
1632}
1633
1645void Abc_NtkRandFile( char * pFileName, int nVars, int nFuncs, int nMints )
1646{
1647 int i, k, nWords = Abc_TtWordNum(nVars);
1648 Vec_Wrd_t * vTruths = Vec_WrdStart( nWords * nFuncs );
1649 Abc_Random(1);
1650 for ( i = 0; i < nFuncs; i++ ) {
1651 word * pTruth = Vec_WrdEntryP(vTruths, i*nWords);
1652 if ( nMints == 0 )
1653 for ( k = 0; k < nWords; k++ )
1654 pTruth[k] = Abc_RandomW(0);
1655 else {
1656 for ( k = 0; k < nMints; k++ ) {
1657 int iMint = 0;
1658 do iMint = Abc_Random(0) % (1 << nVars);
1659 while ( Abc_TtGetBit(pTruth, iMint) );
1660 Abc_TtSetBit( pTruth, iMint );
1661 }
1662 }
1663 }
1664 Vec_WrdWriteTruthHex( pFileName, vTruths, nVars );
1665 if ( nMints )
1666 printf( "Generated %d random %d-variable functions with %d positive minterms and dumped them into file \"%s\".\n",
1667 nFuncs, nVars, nMints, pFileName );
1668 else
1669 printf( "Generated %d random %d-variable functions and dumped them into file \"%s\".\n",
1670 nFuncs, nVars, pFileName );
1671 Vec_WrdFree( vTruths );
1672}
1673
1677
1678
1680
Abc_Ntk_t * Abc_NtkLutCascadeGen(int nLutSize, int nStages, int nRails, int nShared, int fVerbose)
Definition abcCas.c:949
void Abc_LutCasFree(Abc_LutCas_t *p)
Definition abcCas.c:1028
Abc_LutCas_t * Abc_LutCasAlloc(Abc_Ntk_t *pNtk, int nLutsMax, int nIters, int fDelayLut, int fDelayRoute, int fDelayDirect, int fVerbose)
Definition abcCas.c:1004
void Abc_LutCascadeDerive(word *p, int nVars, int nBVars, int Myu, word *pRem, word *pDec, int nStep)
Definition abcCas.c:661
int Abc_NtkFindPathTimeR_rec(Abc_LutCas_t *p, Abc_Obj_t *pObj)
Definition abcCas.c:1085
void Abc_NtkRandFile(char *pFileName, int nVars, int nFuncs, int nMints)
Definition abcCas.c:1645
Abc_Ntk_t * Abc_NtkLutCascadeMap(Abc_Ntk_t *pNtk, int nLutsMax, int nIters, int fDelayLut, int fDelayRoute, int fDelayDirect, int fVerbose)
Definition abcCas.c:1346
Vec_Wec_t * Abc_NtkProfileCascades(Abc_Ntk_t *pNtk, Vec_Int_t *vTrace)
Definition abcCas.c:1273
int Abc_NtkFindPathTimeR(Abc_LutCas_t *p)
Definition abcCas.c:1100
void Abc_LutCascadeMinBase(word *pLuts, int nVars)
Definition abcCas.c:533
word * Abc_LutCascadeGenTest()
Definition abcCas.c:365
char Abc_LutCascadeChar(int iVar, int nVars)
Definition abcCas.c:386
void Abc_LutCasAssignNames(Abc_Ntk_t *pNtk, Abc_Ntk_t *pNtkNew, Vec_Wec_t *vCascs)
Definition abcCas.c:1307
word * Abc_LutCascadeGen(int nVars, int nLutSize, int nRails, int nShared)
Definition abcCas.c:431
int Abc_NtkUpdateNodeD(Abc_LutCas_t *p, Abc_Obj_t *pObj)
Definition abcCas.c:1140
void Abc_LutCascadePrintLut(word *pLuts, int n, int i, int nLutSize, int nVars)
Definition abcCas.c:392
void Abc_NtkSuppMinFile(char *pFileName)
Definition abcCas.c:1569
Abc_Obj_t * Abc_NtkLutCascadeDeriveSop(Abc_Ntk_t *pNtkNew, Abc_Obj_t *pNodeNew, word *pT, int nIns, Vec_Int_t *vCover)
Definition abcCas.c:814
void Abc_BSEvalFree(Abc_BSEval_t *p)
Definition utilBSet.c:565
int Abc_LutCascadeCount(word *pLuts)
Definition abcCas.c:553
word * Abc_LutCascadeTest(Mini_Aig_t *p, int nLutSize, int fVerbose)
Definition abcCas.c:557
Abc_Ntk_t * Abc_NtkLutCascadeFromLuts(word *pLuts, int nVars, Abc_Ntk_t *pNtk, int nLutSize, int fVerbose)
Definition abcCas.c:830
Abc_BSEval_t * Abc_BSEvalAlloc()
Definition utilBSet.c:556
int Abc_NtkUpdateNodeR(Abc_LutCas_t *p, Abc_Obj_t *pObj)
Definition abcCas.c:1153
Abc_Ntk_t * Abc_NtkLutCascadeOne(Abc_Ntk_t *pNtk, int nLutSize, int nStages, int nRails, int nIters, int nJRatio, int nZParam, int fXRail, int Seed, int fVerbose, int fVeryVerbose, char *pGuide)
Definition abcCas.c:893
int Abc_NtkFindPathTimeD_rec(Abc_LutCas_t *p, Abc_Obj_t *pObj)
Definition abcCas.c:1056
void Abc_LutCascadeGenOne(Vec_Wrd_t *vRes, int nIns, int *pIns, int Out, word *p)
Definition abcCas.c:414
void Abc_TtPermuteMask(word *p, int nVars, int Mask, Vec_Int_t *vPerm)
Definition abcCas.c:610
int Abc_NtkFindTiming(Abc_LutCas_t *p)
Definition abcCas.c:1130
void Abc_LutCascadePrint(word *pLuts, int nLutSize)
Definition abcCas.c:407
int Abc_NtkAddEdges(Abc_LutCas_t *p)
Definition abcCas.c:1238
Abc_Ntk_t * Abc_NtkLutCascade(Abc_Ntk_t *pNtk, int nLutSize, int nStages, int nRails, int nIters, int fVerbose)
Definition abcCas.c:878
void Vec_WrdWriteTruthHex(char *pFileName, Vec_Wrd_t *vTruths, int nVars)
Definition abcCas.c:1559
word * Abc_LutCascadeTruth(word *pLuts, int nVars)
Definition abcCas.c:501
int Abc_LutCascadeLookup(word *pStore, int nFuncs, word *pFunc, int nWords)
Definition abcCas.c:651
void Abc_NtkLutCascadeDumpResults(char *pDumpFile, char *pTest, int Nodes, int Edges, int Levs, int DelStart, int DelStop, float DelRatio, int EdgesUsed, float EdgeRatio, int Cascs, float AveLength, abctime time)
Definition abcCas.c:1327
int Abc_NtkUpdateTiming(Abc_LutCas_t *p, int Node, int Fanin)
Definition abcCas.c:1166
word * Abc_LutCascade(Mini_Aig_t *p, int nLutSize, int nStages, int nRails, int nIters, int fVerbose)
Definition abcCas.c:335
struct Abc_BSEval_t_ Abc_BSEval_t
Definition abcCas.c:741
Vec_Wrd_t * Abc_NtkLutCasReadTruths(char *pFileName, int nVarsOrig)
Definition abcCas.c:1390
struct Abc_LutCas_t_ Abc_LutCas_t
Definition abcCas.c:979
int Abc_TtGetGuide(char *pGuide, int Iter, Vec_Int_t *vVarIDs, int fShared)
Definition abcCas.c:578
int Abc_NtkFindPathTimeD(Abc_LutCas_t *p)
Definition abcCas.c:1071
ABC_NAMESPACE_IMPL_START Abc_Ntk_t * Abc_NtkCascade(Abc_Ntk_t *pNtk, int nLutSize, int fCheck, int fVerbose)
DECLARATIONS ///.
Definition abcCas.c:334
word * Abc_LutCascadeDec(Abc_BSEval_t *p, char *pGuide, word *pTruth, int nVarsOrig, Vec_Int_t *vVarIDs, int nRails, int nLutSize, int nStages, int fUseRand, int nZParam, int fXRail, int fVerbose, int *pnStages, int *pMyu)
Definition abcCas.c:745
void Abc_NtkFindCriticalEdges(Abc_LutCas_t *p)
Definition abcCas.c:1114
void Abc_NtkLutCascadeFile(char *pFileName, int nVarsOrig, int nLutSize, int nStages, int nRails, int nIters, int nJRatio, int nZParam, int Seed, int fVerbose, int fVeryVerbose, int fPrintMyu, int fPrintLev, int fXRail)
Definition abcCas.c:1437
int nWords
Definition abcNpn.c:127
Gia_Man_t * Abc_NtkStrashToGia(Abc_Ntk_t *pNtk)
Definition abcUtil.c:3214
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
#define Abc_NtkForEachCo(pNtk, pCo, i)
Definition abc.h:522
ABC_DLL Abc_Ntk_t * Abc_NtkAlloc(Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan)
DECLARATIONS ///.
Definition abcNtk.c:53
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
Definition abcFanio.c:84
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeConst1(Abc_Ntk_t *pNtk)
Definition abcObj.c:643
ABC_DLL int Abc_NtkCheck(Abc_Ntk_t *pNtk)
FUNCTION DEFINITIONS ///.
Definition abcCheck.c:64
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeConst0(Abc_Ntk_t *pNtk)
Definition abcObj.c:612
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition abc.h:527
#define Abc_ObjForEachFanout(pObj, pFanout, i)
Definition abc.h:529
ABC_DLL void Abc_SopComplement(char *pSop)
Definition abcSop.c:648
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
ABC_DLL char * Abc_ObjAssignName(Abc_Obj_t *pObj, char *pName, char *pSuffix)
Definition abcNames.c:69
@ ABC_NTK_LOGIC
Definition abc.h:57
ABC_DLL char * Abc_SopCreateAnd(Mem_Flex_t *pMan, int nVars, int *pfCompl)
Definition abcSop.c:168
ABC_DLL void * Abc_NtkFreeGlobalBdds(Abc_Ntk_t *pNtk, int fFreeMan)
ABC_DLL int Abc_NtkLevel(Abc_Ntk_t *pNtk)
Definition abcDfs.c:1449
ABC_DLL void * Abc_NtkBuildGlobalBdds(Abc_Ntk_t *pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose)
ABC_DLL char * Abc_SopCreateFromIsop(Mem_Flex_t *pMan, int nVars, Vec_Int_t *vCover)
Definition abcSop.c:424
#define Abc_NtkForEachCi(pNtk, pCi, i)
Definition abc.h:518
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
Definition abcNtk.c:1421
@ ABC_FUNC_SOP
Definition abc.h:65
#define Abc_NtkForEachObjVec(vIds, pNtk, pObj, i)
Definition abc.h:455
ABC_DLL Abc_Ntk_t * Abc_NtkStartFrom(Abc_Ntk_t *pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func)
Definition abcNtk.c:157
ABC_DLL Abc_Ntk_t * Abc_NtkDup(Abc_Ntk_t *pNtk)
Definition abcNtk.c:472
ABC_DLL int Abc_NtkGetTotalFanins(Abc_Ntk_t *pNtk)
Definition abcUtil.c:520
#define Abc_NtkForEachNode(pNtk, pNode, i)
Definition abc.h:464
word Abc_RandomW(int fReset)
Definition utilSort.c:1022
#define ABC_SWAP(Type, a, b)
Definition abc_global.h:253
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_PRT(a, t)
Definition abc_global.h:255
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
unsigned Abc_Random(int fReset)
Definition utilSort.c:1004
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_CONST(number)
PARAMETERS ///.
Definition abc_global.h:240
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
char Char
int Abc_CascadeExperiment(char *pFileGeneric, DdManager *dd, DdNode **pOutputs, int nInputs, int nOutputs, int nLutSize, int fCheck, int fVerbose)
EXTERNAL FUNCTIONS ///.
Definition casCore.c:79
#define Len
Definition deflate.h:78
Cube * p
Definition exorList.c:222
char * Extra_UtilStrsav(const char *s)
char * Extra_FileNameGeneric(char *FileName)
Mini_Aig_t * Gia_ManToMiniAig(Gia_Man_t *pGia)
Definition giaMini.c:118
void Gia_ManStop(Gia_Man_t *p)
Definition giaMan.c:82
int Gia_FileSize(char *pFileName)
FUNCTION DECLARATIONS ///.
Definition giaAiger.c:64
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
word * Gia_ObjComputeTruthTable(Gia_Man_t *p, Gia_Obj_t *pObj)
Definition giaTruth.c:447
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
int Kit_TruthIsop(unsigned *puTruth, int nVars, Vec_Int_t *vMemory, int fTryBoth)
Definition kitIsop.c:134
struct Mini_Aig_t_ Mini_Aig_t
BASIC TYPES ///.
Definition miniaig.h:48
struct Mem_Flex_t_ Mem_Flex_t
Definition mem.h:34
void Nm_ManDeleteIdName(Nm_Man_t *p, int ObjId)
Definition nmApi.c:149
Vec_Int_t * vCrits[2]
Definition abcCas.c:995
int fDelayRoute
Definition abcCas.c:989
Abc_Ntk_t * pNtk
Definition abcCas.c:983
int fDelayLut
Definition abcCas.c:988
Vec_Int_t * vPath[2]
Definition abcCas.c:996
int fDelayDirect
Definition abcCas.c:990
Vec_Int_t * vTraceBest
Definition abcCas.c:1001
Vec_Int_t * vTrace
Definition abcCas.c:1000
Vec_Int_t * vCands
Definition abcCas.c:999
Vec_Wec_t * vStack
Definition abcCas.c:997
Vec_Int_t * vTime[2]
Definition abcCas.c:994
Vec_Int_t * vZeroSlack
Definition abcCas.c:998
char * pName
Definition abc.h:158
void * pManFunc
Definition abc.h:191
Nm_Man_t * pManName
Definition abc.h:160
char * pSpec
Definition abc.h:159
void * pData
Definition abc.h:145
int Id
Definition abc.h:132
Abc_Obj_t * pCopy
Definition abc.h:148
unsigned Level
Definition abc.h:142
Vec_Wrd_t * Abc_TtFindBVarsSVars2(Abc_BSEval_t *p, word *pTruth, int nVars, int nCVars, int nRails, int nLutSize, int fVerbose, int *pMyu, int nMyuIncrease)
Definition utilBSet.c:1009
#define assert(ex)
Definition util_old.h:213
char * memcpy()
int strlen()
char * sprintf()
char * strtok()
char * strstr()
#define Vec_IntForEachEntryDouble(vVec, Entry1, Entry2, i)
Definition vecInt.h:72
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
Definition vecWec.h:55
#define Vec_WecForEachLevelReverseStartStop(vGlob, vVec, i, LevelStart, LevelStop)
Definition vecWec.h:67
#define Vec_WecForEachLevelStart(vGlob, vVec, i, LevelStart)
Definition vecWec.h:59
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
Definition vecWec.h:42
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.
Definition vecWrd.h:42