47extern int Abc_CascadeExperiment(
char * pFileGeneric, DdManager * dd, DdNode ** pOutputs,
int nInputs,
int nOutputs,
int nLutSize,
int fCheck,
int fVerbose );
71 int fBddSizeMax = 500000;
75 assert( Abc_NtkIsStrash(pNtk) );
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 );
88 dd = (DdManager *)Abc_NtkGlobalBddMan( pNtk );
89 ppOutputs =
ABC_ALLOC( DdNode *, Abc_NtkCoNum(pNtk) );
91 ppOutputs[i] = (DdNode *)Abc_ObjGlobalBdd(pNode);
95 if ( !
Abc_CascadeExperiment( pFileGeneric, dd, ppOutputs, Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), nLutSize, fCheck, fVerbose ) )
113 printf(
"Abc_NtkCollapse: The network check has failed.\n" );
131void Abc_LutBddTestPrint( DdManager * dd,
Vec_Ptr_t * vNodes,
Vec_Wrd_t * vMasks,
char ** ppNames,
int nNames )
133 DdNode * node;
int i, k;
136 if (Cudd_IsConstant(node))
137 printf(
"ID = %2d value = %d ", (
int)node->Id, (
int)Cudd_V(node) );
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 ) {
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 )
149 int Val = (((Mask >> Abc_Var2Lit(k, 0)) & 1) << 1) | ((Mask >> Abc_Var2Lit(k, 1)) & 1);
151 printf(
"%c%s",
'-', ppNames[k] );
153 printf(
"%c%s",
'+', ppNames[k] );
163DdManager * s_ddd = NULL;
164int Abc_LutBddCompare( DdNode ** pp1, DdNode ** pp2 )
166 DdNode * pObj1 = *pp1;
167 DdNode * pObj2 = *pp2;
168 return Cudd_ReadPerm(s_ddd, pObj1->index) - Cudd_ReadPerm(s_ddd, pObj2->index);
170void Abc_LutBddTest( DdManager * dd, DdNode * bFunc,
char ** ppNames,
int nNames,
int nVars )
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 );
178 Vec_PtrSort( vNodes, (
int (*)(
const void *,
const void *))Abc_LutBddCompare );
182 Vec_Int_t * vLevels = Vec_IntAlloc( Vec_PtrSize(vNodes) );
185 Vec_IntPush( vLevels, Cudd_ReadPerm(dd, node->index) );
187 assert( Vec_IntSize(vLevels) == Vec_PtrSize(vNodes) );
189 printf(
"Size = %d. Fanins = %d. Vars = %d. Nodes = %d.\n", dd->size, nNames, nVars, Vec_PtrSize(vNodes) );
192 if (Cudd_IsConstant(node))
193 printf(
"ID = %2d value = %d\n", (
int)node->Id, (
int)Cudd_V(node) );
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);
199 Vec_Wec_t * vCofs = Vec_WecStart( nNames+1 );
200 Vec_WecPush( vCofs, 0, 0 );
202 if ( Cudd_IsConstant(node) )
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 );
212 Vec_WecPrint( vCofs, 0 );
215 Vec_Wrd_t * vMasks = Vec_WrdStart( Vec_PtrSize(vNodes) );
218 if ( i == Vec_WecSize(vCofs)-1 )
223 printf(
"Level %2d : ", i );
224 for ( k = 0; k < nNames; k++ ) {
225 if ( Cudd_ReadPerm(dd, k) >= i )
228 for ( f = 0; f < 2; f++ )
230 if ( (Vec_WrdEntry(vMasks, Obj) >> Abc_Var2Lit(k, !f)) & 1 )
232 printf(
"%s(%d:%d) ", ppNames[k], Counts[0], Counts[1] );
238 DdNode * node = (DdNode *)Vec_PtrEntry( vNodes, Obj );
239 if ( Cudd_IsConstant(node) )
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 )
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));
326 Vec_IntFree( vLevels );
327 Vec_WecFree( vCofs );
328 Vec_PtrFree( vNodes );
329 Vec_WrdFree( vMasks );
373 for ( i = 0; i < 6; i++ )
376 pLuts[1+9] =
ABC_CONST(0x8000000000000000);
380 for ( i = 0; i < 4; i++ )
381 pLuts[11+2+i] = i ? i + 5 : 9;
383 pLuts[11+7] =
ABC_CONST(0xFFFEFFFEFFFEFFFE);
390 return 'A'+(iVar-nVars);
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 );
399 for ( k = nLutSize-1; k >= nIns; k-- )
401 for ( k = nIns-1; k >= 0; k-- )
404 Abc_TtPrintHexRev( stdout, pT, nIns );
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] )
416 int w,
nWords = Abc_TtWordNum(nIns);
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 );
425 Vec_WrdPush( vRes,
p ?
p[0] : Abc_Tt6Stretch(
Abc_Random(0), nIns) );
427 for ( w = 0; w <
nWords; w++ )
433 assert( nLutSize - nRails - nShared > 0 );
435 Vec_Int_t * vFanins = Vec_IntAlloc( nLutSize );
436 Vec_Int_t * vVars = Vec_IntStartNatural( nVars );
437 Vec_Str_t * vGuide = Vec_StrAlloc( 100 );
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++ )
444 Vec_StrPush( vGuide,
'0'+c++ );
445 Vec_IntClear( vFanins );
446 for ( i = 0; i < nShared; i++ ) {
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) );
453 for ( i = 0; i < nLutSize - nRails - nShared; i++ ) {
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 );
461 if ( Vec_WrdSize(vRes) == 1 ) {
462 for ( i = 0; i < nRails; i++ ) {
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 );
473 for ( i = 0; i < nRails; i++ ) {
474 Vec_IntPush( vFanins, iVarPrev+i );
475 Vec_StrPush( vGuide,
'a'+iVarPrev+i );
479 assert( Vec_IntSize(vFanins) == nLutSize );
480 for ( i = 0; i < nRails; i++ ) {
482 Vec_IntPush( vVars, iVarPrev+i );
485 assert( Vec_IntSize(vVars) <= nLutSize );
487 Vec_StrPush( vGuide,
'0'+c++ );
489 Vec_StrPush( vGuide,
'a'+Obj );
490 Vec_StrPush( vGuide,
'\0' );
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 );
497 word * pRes = Vec_WrdReleaseArray(vRes);
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] )
510 word nIns = pLuts[i+1];
511 word * pIns = pLuts+i+2;
512 word * pT = pLuts+i+2+nIns+1;
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) )
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);
526 iLastLut = pIns[nIns];
528 word * pRes = Vec_WrdReleaseArray(vFuncs);
530 Vec_WrdFree( vFuncs );
535 int i, n, v, pFans[32];
536 for ( n = 0, i = 1; n < pLuts[0]; n++, i += pLuts[i] )
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) );
555 return (
int)pLuts[0];
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 )
587 assert( pGuide[i] ==
'0'+Iter );
588 for ( i++; pGuide[i]; i++ )
590 char Char = pGuide[i];
593 if ( fShared &&
Char >=
'a' &&
Char <=
'z' )
598 else if (
Char >=
'A' &&
Char <=
'Z' )
601 int iPlace = Vec_IntFind(vVarIDs, Value);
603 assert( ((Res >> iPlace) & 1) == 0 );
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;
617 for ( v = 0; v < nVars; v++ )
618 printf(
"%c ",
'a'+Vec_IntEntry(vPerm, v) );
621 for ( v = 0; v < nVars; v++ )
622 printf(
"%c ", (Mask >> v) & 1 ?
'1' :
'-' );
625 for ( v = nVars-1; v >= 0; v-- ) {
626 if ( ((Mask >> v) & 1) == 0 )
633 for ( i = v; i < iLast; i++ ) {
634 Abc_TtSwapAdjacent(
p,
nWords, i );
635 if ( pPerm )
ABC_SWAP(
int, pPerm[i], pPerm[i+1] )
641 for ( v = 0; v < nVars; v++ )
642 printf(
"%c ",
'a'+Vec_IntEntry(vPerm, v) );
654 for ( i = 0; i < nFuncs; i++ )
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;
668 for ( m = 0; m < (1 << nBVars); m++ ) {
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);
679 for ( m = nFuncs; m < (1 << nEVars); m++ )
680 Abc_TtCopy( pRem+m*nFWords, pRem+iFunc*nFWords, nFWords, 0 );
682 for ( e = 0; e < nEVars; e++ )
683 pDec[e*nStep] = Abc_Tt6Stretch( pDec[e*nStep], nBVars );
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 )
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 );
699 int mSVars = pGuide ?
Abc_TtGetGuide(pGuide, Iter, vVarIDs, 1) : (Guide >> 24) & 0xFFFFFF;
700 int nSVars = __builtin_popcount(mSVars);
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 );
711 int nWordsRem = Abc_TtWordNum(nAVars+nFVars+nEVars+nSVars);
712 Vec_WrdFill( vFuncs[1], nWordsRem, 0 );
713 word * pRem = Vec_WrdArray(vFuncs[1]);
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++ )
724 pRem+m*nWordsRem/nSMints, pDec+m*nWordsStep, nWordsDec );
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 );
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 )
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;
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 );
763 if ( i+2 > nStages ) {
765 printf(
"The length of the cascade (%d) exceeds the max allowed number of stages (%d).\n", i+2, nStages );
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 );
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 );
777 if ( i+2 > nStages ) {
779 printf(
"The length of the cascade (%d) exceeds the max allowed number of stages (%d).\n", i+2, nStages );
783 if ( nRVars == -1 ) {
784 Vec_IntClear( vVarIDs );
786 printf(
"The function is not decomposable with %d rails.\n", nRails );
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;
797 for ( i = 0; i < 3; i++ )
798 Vec_WrdFree( vFuncs[i] );
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) ) {
826 pNodeNew->
pData = pSop;
833 Abc_Obj_t * pObj;
int Id;
char pName[2] = {0};
842 for ( Id = 0; Id <
nVars; Id++ ) {
843 pObj = Abc_NtkCreatePi(pNtkNew);
847 pObj = Abc_NtkCreatePo(pNtkNew);
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] )
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++ )
863 Vec_PtrWriteEntry( vCopy, pIns[nIns], pObjNew );
864 iLastLut = pIns[nIns];
866 Vec_IntFree( vCover );
867 assert( Abc_NtkCoNum(pNtkNew) == 1 );
869 Vec_PtrFree( vCopy );
872 printf(
"Abc_NtkLutCascadeFromLuts: The network check has failed.\n" );
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 )
896 int i,
nWords = Abc_TtWordNum(Abc_NtkCiNum(pNtk));
901 for ( i = 0; i < Seed; i++ )
904 for (
int Iter = 0; Iter < nIters; Iter++ ) {
906 Abc_TtCopy( pCopy, pTruth1,
nWords, 0 );
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 );
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 );
918 printf(
" using structural info: %s", pGuide );
922 word * pLuts =
Abc_LutCascadeDec(
p, pGuide, pTruth1, Abc_NtkCiNum(pNtk), vVarIDs, nRails, nLutSize, nStages, (
int)(Iter >= 0), nZParam, fXRail, fVeryVerbose, NULL, NULL );
924 Vec_IntFree( vVarIDs );
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" );
937 printf(
"Verification passed.\n" );
951 int nVars = nStages * nLutSize - (nStages-1) * (nRails + nShared);
958 printf(
"Function: "); Abc_TtPrintHexRev( stdout, pTruth,
nVars ); printf(
"\n" );
1009 p->nLutsMax = nLutsMax;
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) );
1022 p->vZeroSlack = Vec_IntAlloc( 1000 );
1023 p->vCands = Vec_IntAlloc( 1000 );
1024 p->vTrace = Vec_IntAlloc( 1000 );
1025 p->vTraceBest = Vec_IntAlloc( 1000 );
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 );
1058 if ( !Abc_ObjIsNode(pObj) || !Abc_ObjFaninNum(pObj) )
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;
1065 Delay += Vec_IntEntry(
p->vPath[0], pObj->
Id) == pNext->
Id ?
p->fDelayDirect :
p->fDelayRoute;
1066 DelayMax = Abc_MaxInt( DelayMax, Delay +
p->fDelayLut );
1068 Vec_IntWriteEntry(
p->vTime[0], pObj->
Id, DelayMax );
1073 Abc_Obj_t * pObj;
int i, Delay, DelayMax = 0;
1074 Vec_IntFill(
p->vTime[0], Abc_NtkObjNumMax(
p->pNtk), 0 );
1077 DelayMax = Abc_MaxInt( DelayMax, Delay +
p->fDelayRoute );
1079 Vec_IntClear(
p->vCrits[0] );
1081 if ( DelayMax == Vec_IntEntry(
p->vTime[0], Abc_ObjFaninId0(pObj)) +
p->fDelayRoute )
1082 Vec_IntPush(
p->vCrits[0], pObj->
Id );
1087 if ( Abc_ObjIsCo(pObj) )
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;
1094 Delay += Vec_IntEntry(
p->vPath[0], pNext->
Id) == pObj->
Id ?
p->fDelayDirect :
p->fDelayRoute;
1095 DelayMax = Abc_MaxInt( DelayMax, Delay );
1097 Vec_IntWriteEntry(
p->vTime[1], pObj->
Id, DelayMax );
1098 return DelayMax + (Abc_ObjIsNode(pObj) ?
p->fDelayLut : 0);
1102 Abc_Obj_t * pObj;
int i;
int Delay, DelayMax = 0;
1103 Vec_IntFill(
p->vTime[1], Abc_NtkObjNumMax(
p->pNtk), 0 );
1106 DelayMax = Abc_MaxInt( DelayMax, Delay );
1108 Vec_IntClear(
p->vCrits[1] );
1110 if ( DelayMax == Vec_IntEntry(
p->vTime[1], pObj->
Id) )
1111 Vec_IntPush(
p->vCrits[1], pObj->
Id );
1117 Vec_IntClear(
p->vCands );
1119 if ( Vec_IntEntry(
p->vPath[0], pObj->
Id) )
1121 if ( Vec_IntEntry(
p->vTime[0], pObj->
Id) + Vec_IntEntry(
p->vTime[1], pObj->
Id) <
p->DelayMax )
1123 assert( Vec_IntEntry(
p->vTime[0], pObj->
Id) + Vec_IntEntry(
p->vTime[1], pObj->
Id ==
p->DelayMax) );
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 );
1134 assert( Delay0 == Delay1 );
1135 p->DelayMax = Delay0;
1142 Abc_Obj_t * pNext;
int i;
int Delay, DelayMax = 0;
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 );
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;
1155 Abc_Obj_t * pNext;
int i;
float Delay, DelayMax = 0;
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 );
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;
1168 Abc_Obj_t * pNode = Abc_NtkObj(
p->pNtk, Node );
1169 Abc_Obj_t * pFanin = Abc_NtkObj(
p->pNtk, Fanin );
1171 assert( Abc_ObjIsNode(pNode) && Abc_ObjIsNode(pFanin) );
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 );
1184 if ( Abc_NodeIsTravIdCurrent(pNext) || Abc_ObjIsCo(pNext) )
1186 Abc_NodeSetTravIdCurrent( pNext );
1187 Vec_WecPush(
p->vStack, pNext->
Level, pNext->
Id );
1195 if ( Abc_NodeIsTravIdCurrent(pNext) )
1197 Abc_NodeSetTravIdCurrent( pNext );
1198 Vec_WecPush(
p->vStack, pNext->
Level, pNext->
Id );
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 );
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;
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 );
1221 int DelayOld =
p->DelayMax;
1223 assert( DelayOld >
p->DelayMax );
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 );
1246 printf(
"Start : %d\n",
p->DelayMax );
1247 int i, LastChange = 0;
1248 for ( i = 0; i < nEdgesMax; i++ )
1250 float DelayPrev =
p->DelayMax;
1251 if ( Vec_IntSize(
p->vCands) == 0 )
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 );
1263 assert( DelayPrev >=
p->DelayMax );
1264 if ( DelayPrev >
p->DelayMax )
1266 DelayPrev =
p->DelayMax;
1268 printf(
"%5d : %d : %4d -> %4d\n", i,
p->DelayMax, Fanin, Node );
1270 Vec_IntShrink(
p->vTrace, 2*LastChange );
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;
1281 assert( Vec_IntEntry(vPath, Node) == 0 );
1282 Vec_IntWriteEntry( vPath, Node, Fanin );
1283 Vec_IntWriteEntry( vMap, Fanin, 1 );
1286 if ( Vec_IntEntry(vMap, pObj->
Id) )
1288 if ( Vec_IntEntry(vPath, pObj->
Id) == 0 )
1290 Vec_Int_t * vLevel = Vec_WecPushLevel( vCasc );
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 );
1297 printf(
"Cascades: " );
1300 printf(
"%d=%d ", i, Count ), nCascs += Count;
1302 Vec_IntFree( vMap );
1303 Vec_IntFree( vPath );
1304 Vec_IntFree( vCounts );
1310 Vec_Int_t * vMap = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
1312 Vec_IntWriteEntry( vMap, Abc_ObjFaninId0(pObj), pObj->
Id );
1315 assert( Abc_ObjIsNode(pObj) );
1316 sprintf( pName,
"c%d_n%d", i, k );
1317 if ( Vec_IntEntry(vMap, pObj->
pCopy->
Id) == 0 )
1325 Vec_IntFree( vMap );
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 )
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" );
1353 Vec_IntFill(
p->vTraceBest, Abc_NtkNodeNum(pNtk), 0 );
1354 for ( i = 0; i < nIters; i++ )
1357 printf(
"ITERATION %2d:\n", i );
1359 if ( DelayBest < Delay || (DelayBest == Delay && Vec_IntSize(
p->vTraceBest) <= Vec_IntSize(
p->vTrace)) )
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 );
1374 Vec_WecFree( vCascs );
1393 int nWords = Abc_TtWordNum(nVarsOrig);
1395 FILE * pFile = fopen( pFileName,
"rb" );
1396 if ( pFile == NULL ) { printf(
"Cannot open file \"%s\" for reading.\n", pFileName);
return NULL; }
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 )
1403 if ( pToken[0] ==
'0' && pToken[1] ==
'x' )
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 );
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 );
1415 if ( vTruths == NULL )
1416 vTruths = Vec_WrdAlloc( 10000 );
1417 for (
int w = 0; w <
nWords; w++ )
1418 Vec_WrdPush( vTruths, pTruth[w] );
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 )
1439 abctime clkStart = Abc_Clock();
1440 int i, nErrors = 0, Sum = 0, nStageCount = 0, MyuMin = 0, nTotalLuts = 0,
nWords = Abc_TtWordNum(nVarsOrig);
1442 if (
strstr(pFileName,
".txt") )
1445 vTruths = Vec_WrdReadBin( pFileName, 0 );
1446 if ( vTruths == NULL )
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 );
1457 for ( i = 0; i < Seed; i++ )
1459 printf(
"Considering %d functions having %d variables from file \"%s\".\n", nFuncs, nVarsOrig, pFileName );
1461 int Iter = 0, IterReal = 0, LutStats[50] = {0}, StageStats[50] = {0}, MyuStats[50] = {0};
1463 for ( i = 0; i < nFuncs; i++ )
1465 word * pTruth = Vec_WrdEntryP( vTruths, i*
nWords );
1466 Abc_TtCopy( pCopy, pTruth,
nWords, 0 );
1470 if ( fVerbose || fVeryVerbose )
1471 printf(
"Function %4d : ", i );
1473 Abc_TtPrintHexRev( stdout, pTruth, nVarsOrig ), printf(
"\n" );
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 );
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 ) {
1495 if ( fVerbose || fVeryVerbose )
1496 printf(
"Not decomposable.\n" );
1504 if ( nStageCount < 50) StageStats[nStageCount]++;
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" ); }
1517 else if ( fVerbose || fVeryVerbose )
1518 printf(
"Verification passed.\n" );
1524 Vec_WrdFree( vTruths );
1526 printf(
"Column multiplicity statistics for %d-rail LUT cascade:\n", nRails );
1527 for ( i = 0; i < 50; i++ )
1529 printf(
" %2d Myu : Function count = %8d (%6.2f %%)\n", i, MyuStats[i], 100.0*MyuStats[i]/Abc_MaxInt(1, nFuncs)/IterReal );
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) );
1537 printf(
"LUT count statistics for %d-rail LUT cascade:\n", nRails );
1538 for ( i = 0; i < 50; 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 );
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;
1565 for ( i = 0; i < nFuncs; i++ )
1566 Abc_TtPrintHexRev( pFile, Vec_WrdEntryP(vTruths, i*
nWords), nVars ), fprintf( pFile,
"\n" );
1572 FILE * pFile = fopen( pFileName,
"rb" );
1573 if ( pFile == NULL ) { printf(
"Cannot open file \"%s\" for reading.\n", pFileName);
return; }
1575 char * pToken, * pLine =
ABC_ALLOC(
char, nFileSize );
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 )
1582 if ( pToken[0] ==
'0' && pToken[1] ==
'x' )
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 );
1592 if ( !Abc_TtReadHex( pTruth, pToken ) ) {
1593 printf(
"Line %d has truth table that cannot be read correctly (%s).\n", i, pToken );
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] );
1611 for ( nVars = 0; nVars < 32; nVars++ )
1612 if ( pvTruths[nVars] )
1613 Vec_WrdFreeP( &pvTruths[nVars] );
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 )
1624 char pFileName2[1000];
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] );
1647 int i, k,
nWords = Abc_TtWordNum(nVars);
1650 for ( i = 0; i < nFuncs; i++ ) {
1651 word * pTruth = Vec_WrdEntryP(vTruths, i*
nWords);
1653 for ( k = 0; k <
nWords; k++ )
1656 for ( k = 0; k < nMints; k++ ) {
1659 while ( Abc_TtGetBit(pTruth, iMint) );
1660 Abc_TtSetBit( pTruth, iMint );
1666 printf(
"Generated %d random %d-variable functions with %d positive minterms and dumped them into file \"%s\".\n",
1667 nFuncs, nVars, nMints, pFileName );
1669 printf(
"Generated %d random %d-variable functions and dumped them into file \"%s\".\n",
1670 nFuncs, nVars, pFileName );
1671 Vec_WrdFree( vTruths );
Abc_Ntk_t * Abc_NtkLutCascadeGen(int nLutSize, int nStages, int nRails, int nShared, int fVerbose)
void Abc_LutCasFree(Abc_LutCas_t *p)
Abc_LutCas_t * Abc_LutCasAlloc(Abc_Ntk_t *pNtk, int nLutsMax, int nIters, int fDelayLut, int fDelayRoute, int fDelayDirect, int fVerbose)
void Abc_LutCascadeDerive(word *p, int nVars, int nBVars, int Myu, word *pRem, word *pDec, int nStep)
int Abc_NtkFindPathTimeR_rec(Abc_LutCas_t *p, Abc_Obj_t *pObj)
void Abc_NtkRandFile(char *pFileName, int nVars, int nFuncs, int nMints)
Abc_Ntk_t * Abc_NtkLutCascadeMap(Abc_Ntk_t *pNtk, int nLutsMax, int nIters, int fDelayLut, int fDelayRoute, int fDelayDirect, int fVerbose)
Vec_Wec_t * Abc_NtkProfileCascades(Abc_Ntk_t *pNtk, Vec_Int_t *vTrace)
int Abc_NtkFindPathTimeR(Abc_LutCas_t *p)
void Abc_LutCascadeMinBase(word *pLuts, int nVars)
word * Abc_LutCascadeGenTest()
char Abc_LutCascadeChar(int iVar, int nVars)
void Abc_LutCasAssignNames(Abc_Ntk_t *pNtk, Abc_Ntk_t *pNtkNew, Vec_Wec_t *vCascs)
word * Abc_LutCascadeGen(int nVars, int nLutSize, int nRails, int nShared)
int Abc_NtkUpdateNodeD(Abc_LutCas_t *p, Abc_Obj_t *pObj)
void Abc_LutCascadePrintLut(word *pLuts, int n, int i, int nLutSize, int nVars)
void Abc_NtkSuppMinFile(char *pFileName)
Abc_Obj_t * Abc_NtkLutCascadeDeriveSop(Abc_Ntk_t *pNtkNew, Abc_Obj_t *pNodeNew, word *pT, int nIns, Vec_Int_t *vCover)
void Abc_BSEvalFree(Abc_BSEval_t *p)
int Abc_LutCascadeCount(word *pLuts)
word * Abc_LutCascadeTest(Mini_Aig_t *p, int nLutSize, int fVerbose)
Abc_Ntk_t * Abc_NtkLutCascadeFromLuts(word *pLuts, int nVars, Abc_Ntk_t *pNtk, int nLutSize, int fVerbose)
Abc_BSEval_t * Abc_BSEvalAlloc()
int Abc_NtkUpdateNodeR(Abc_LutCas_t *p, Abc_Obj_t *pObj)
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)
int Abc_NtkFindPathTimeD_rec(Abc_LutCas_t *p, Abc_Obj_t *pObj)
void Abc_LutCascadeGenOne(Vec_Wrd_t *vRes, int nIns, int *pIns, int Out, word *p)
void Abc_TtPermuteMask(word *p, int nVars, int Mask, Vec_Int_t *vPerm)
int Abc_NtkFindTiming(Abc_LutCas_t *p)
void Abc_LutCascadePrint(word *pLuts, int nLutSize)
int Abc_NtkAddEdges(Abc_LutCas_t *p)
Abc_Ntk_t * Abc_NtkLutCascade(Abc_Ntk_t *pNtk, int nLutSize, int nStages, int nRails, int nIters, int fVerbose)
void Vec_WrdWriteTruthHex(char *pFileName, Vec_Wrd_t *vTruths, int nVars)
word * Abc_LutCascadeTruth(word *pLuts, int nVars)
int Abc_LutCascadeLookup(word *pStore, int nFuncs, word *pFunc, int nWords)
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)
int Abc_NtkUpdateTiming(Abc_LutCas_t *p, int Node, int Fanin)
word * Abc_LutCascade(Mini_Aig_t *p, int nLutSize, int nStages, int nRails, int nIters, int fVerbose)
struct Abc_BSEval_t_ Abc_BSEval_t
Vec_Wrd_t * Abc_NtkLutCasReadTruths(char *pFileName, int nVarsOrig)
struct Abc_LutCas_t_ Abc_LutCas_t
int Abc_TtGetGuide(char *pGuide, int Iter, Vec_Int_t *vVarIDs, int fShared)
int Abc_NtkFindPathTimeD(Abc_LutCas_t *p)
ABC_NAMESPACE_IMPL_START Abc_Ntk_t * Abc_NtkCascade(Abc_Ntk_t *pNtk, int nLutSize, int fCheck, int fVerbose)
DECLARATIONS ///.
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)
void Abc_NtkFindCriticalEdges(Abc_LutCas_t *p)
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)
Gia_Man_t * Abc_NtkStrashToGia(Abc_Ntk_t *pNtk)
struct Abc_Obj_t_ Abc_Obj_t
#define Abc_NtkForEachCo(pNtk, pCo, i)
ABC_DLL Abc_Ntk_t * Abc_NtkAlloc(Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan)
DECLARATIONS ///.
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeConst1(Abc_Ntk_t *pNtk)
ABC_DLL int Abc_NtkCheck(Abc_Ntk_t *pNtk)
FUNCTION DEFINITIONS ///.
ABC_DLL Abc_Obj_t * Abc_NtkCreateNodeConst0(Abc_Ntk_t *pNtk)
#define Abc_ObjForEachFanin(pObj, pFanin, i)
#define Abc_ObjForEachFanout(pObj, pFanout, i)
ABC_DLL void Abc_SopComplement(char *pSop)
struct Abc_Ntk_t_ Abc_Ntk_t
ABC_DLL char * Abc_ObjAssignName(Abc_Obj_t *pObj, char *pName, char *pSuffix)
ABC_DLL char * Abc_SopCreateAnd(Mem_Flex_t *pMan, int nVars, int *pfCompl)
ABC_DLL void * Abc_NtkFreeGlobalBdds(Abc_Ntk_t *pNtk, int fFreeMan)
ABC_DLL int Abc_NtkLevel(Abc_Ntk_t *pNtk)
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)
#define Abc_NtkForEachCi(pNtk, pCi, i)
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
#define Abc_NtkForEachObjVec(vIds, pNtk, pObj, i)
ABC_DLL Abc_Ntk_t * Abc_NtkStartFrom(Abc_Ntk_t *pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func)
ABC_DLL Abc_Ntk_t * Abc_NtkDup(Abc_Ntk_t *pNtk)
ABC_DLL int Abc_NtkGetTotalFanins(Abc_Ntk_t *pNtk)
#define Abc_NtkForEachNode(pNtk, pNode, i)
word Abc_RandomW(int fReset)
#define ABC_SWAP(Type, a, b)
#define ABC_ALLOC(type, num)
unsigned Abc_Random(int fReset)
#define ABC_CALLOC(type, num)
#define ABC_CONST(number)
PARAMETERS ///.
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
struct Vec_Str_t_ Vec_Str_t
int Abc_CascadeExperiment(char *pFileGeneric, DdManager *dd, DdNode **pOutputs, int nInputs, int nOutputs, int nLutSize, int fCheck, int fVerbose)
EXTERNAL FUNCTIONS ///.
Mini_Aig_t * Gia_ManToMiniAig(Gia_Man_t *pGia)
void Gia_ManStop(Gia_Man_t *p)
int Gia_FileSize(char *pFileName)
FUNCTION DECLARATIONS ///.
struct Gia_Man_t_ Gia_Man_t
word * Gia_ObjComputeTruthTable(Gia_Man_t *p, Gia_Obj_t *pObj)
unsigned __int64 word
DECLARATIONS ///.
int Kit_TruthIsop(unsigned *puTruth, int nVars, Vec_Int_t *vMemory, int fTryBoth)
struct Mini_Aig_t_ Mini_Aig_t
BASIC TYPES ///.
struct Mem_Flex_t_ Mem_Flex_t
void Nm_ManDeleteIdName(Nm_Man_t *p, int ObjId)
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)
#define Vec_IntForEachEntryDouble(vVec, Entry1, Entry2, i)
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
#define Vec_WecForEachLevelReverseStartStop(vGlob, vVec, i, LevelStart, LevelStop)
#define Vec_WecForEachLevelStart(vGlob, vVec, i, LevelStart)
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.