72#define Fxch_ManForEachCubeVec( vVec, vCubes, vCube, i ) \
73 for ( i = 0; (i < Vec_IntSize(vVec)) && ((vCube) = Vec_WecEntry(vCubes, Vec_IntEntry(vVec, i))); i++ )
75static inline Vec_Int_t * Fxch_ManCube(
Fxch_Man_t *
p,
int hCube ) {
return Vec_WecEntry(&
p->vCubes, Pla_CubeNum(hCube)); }
96 int nVarsInit = Vec_WrdCountZero(vDivs);
97 FILE * pFile = fopen( pFileName,
"wb" );
99 printf(
"Cannot open file \"%s\" for writing.\n", pFileName );
108 fprintf( pFile,
"# BLIF file written via PLA package in ABC on " );
110 fprintf( pFile,
"\n\n" );
112 fprintf( pFile,
".model %s\n", pFileName );
113 fprintf( pFile,
".inputs" );
114 for ( i = 0; i < nVarsInit; i++ )
115 fprintf( pFile,
" i%d", i );
116 fprintf( pFile,
"\n" );
117 fprintf( pFile,
".outputs o" );
118 fprintf( pFile,
"\n" );
120 fprintf( pFile,
".names" );
121 for ( i = 0; i < Vec_WrdSize(vDivs); i++ )
122 fprintf( pFile,
" i%d", i );
123 fprintf( pFile,
" o\n" );
125 vStr = Vec_StrStart( Vec_WrdSize(vDivs) + 1 );
128 if ( !Vec_IntSize(vCube) )
130 for ( k = 0; k < Vec_WrdSize(vDivs); k++ )
131 Vec_StrWriteEntry( vStr, k,
'-' );
133 Vec_StrWriteEntry( vStr, Abc_Lit2Var(Lit), (
char)(Abc_LitIsCompl(Lit) ?
'0' :
'1') );
134 fprintf( pFile,
"%s 1\n", Vec_StrArray(vStr) );
140 int pLits[2] = { (int)(Div & 0xFFFFFFFF), (int)(Div >> 32) };
141 fprintf( pFile,
".names" );
142 fprintf( pFile,
" i%d", Abc_Lit2Var(pLits[0]) );
143 fprintf( pFile,
" i%d", Abc_Lit2Var(pLits[1]) );
144 fprintf( pFile,
" i%d\n", i );
145 fprintf( pFile,
"%d%d 1\n", !Abc_LitIsCompl(pLits[0]), !Abc_LitIsCompl(pLits[1]) );
147 fprintf( pFile,
".end\n\n" );
149 printf(
"Written BLIF file \"%s\".\n", pFileName );
170 p->nVars = Vec_WecSize(vLits)/2;
174 Vec_IntGrow( &
p->vRands, 2*
p->nVars );
175 for ( i = 0; i < 2*
p->nVars; i++ )
178 Vec_IntGrow( &
p->vCubeLinks, Vec_WecSize(&
p->vCubes) );
181 Vec_IntPush( &
p->vCubeLinks,
p->nLits+1 );
182 p->nLits += Vec_IntSize(vCube);
184 assert( Vec_IntSize(&
p->vCubeLinks) == Vec_WecSize(&
p->vCubes) );
186 LogSize = Abc_Base2Log(
p->nLits+1 );
188 p->SizeMask = (1 << LogSize) - 1;
190 assert(
p->nLits+1 <
p->SizeMask+1 );
192 Vec_FltGrow( &
p->vWeights, 1000 );
193 Vec_FltPush( &
p->vWeights, -1 );
194 Vec_WecGrow( &
p->vPairs, 1000 );
195 Vec_WecPushLevel( &
p->vPairs );
197 Vec_WrdGrow( &
p->vDivs,
p->nVars + 1000 );
198 Vec_WrdFill( &
p->vDivs,
p->nVars, 0 );
203 Vec_WecErase( &
p->vCubes );
204 Vec_WecErase( &
p->vLits );
205 Vec_IntErase( &
p->vRands );
206 Vec_IntErase( &
p->vCubeLinks );
207 Hash_IntManStop(
p->vHash );
208 Vec_QueFree(
p->vPrio );
209 Vec_FltErase( &
p->vWeights );
210 Vec_WecErase( &
p->vPairs );
211 Vec_WrdErase( &
p->vDivs );
212 Vec_IntErase( &
p->vCubesS );
213 Vec_IntErase( &
p->vCubesD );
214 Vec_IntErase( &
p->vCube1 );
215 Vec_IntErase( &
p->vCube2 );
231static inline int Fxch_TabCompare(
Fxch_Man_t *
p,
int hCube1,
int hCube2 )
233 Vec_Int_t * vCube1 = Fxch_ManCube(
p, hCube1 );
234 Vec_Int_t * vCube2 = Fxch_ManCube(
p, hCube2 );
235 if ( !Vec_IntSize(vCube1) || !Vec_IntSize(vCube2) || Vec_IntSize(vCube1) != Vec_IntSize(vCube2) )
237 Vec_IntClear( &
p->vCube1 );
238 Vec_IntClear( &
p->vCube2 );
239 Vec_IntAppendSkip( &
p->vCube1, vCube1, Pla_CubeLit(hCube1) );
240 Vec_IntAppendSkip( &
p->vCube2, vCube2, Pla_CubeLit(hCube2) );
241 return Vec_IntEqual( &
p->vCube1, &
p->vCube2 );
247 if ( Vec_IntSize(Vec_WecEntry(&
p->vCubes, hCube)) > 0 )
248 Vec_IntWriteEntry( vLit2Cube, k++, hCube );
249 Vec_IntShrink( vLit2Cube, k );
253 int * pBeg1 = vArr1->pArray;
254 int * pBeg2 = vArr2->pArray;
255 int * pEnd1 = vArr1->pArray + vArr1->nSize;
256 int * pEnd2 = vArr2->pArray + vArr2->nSize;
257 int * pBeg1New = vArr1->pArray;
258 int * pBeg2New = vArr2->pArray;
259 Vec_IntClear( vArr );
260 while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
262 if ( Pla_CubeNum(*pBeg1) == Pla_CubeNum(*pBeg2) )
263 Vec_IntPushTwo( vArr, *pBeg1, *pBeg2 ), pBeg1++, pBeg2++;
264 else if ( *pBeg1 < *pBeg2 )
265 *pBeg1New++ = *pBeg1++;
267 *pBeg2New++ = *pBeg2++;
269 while ( pBeg1 < pEnd1 )
270 *pBeg1New++ = *pBeg1++;
271 while ( pBeg2 < pEnd2 )
272 *pBeg2New++ = *pBeg2++;
273 Vec_IntShrink( vArr1, pBeg1New - vArr1->pArray );
274 Vec_IntShrink( vArr2, pBeg2New - vArr2->pArray );
275 return Vec_IntSize(vArr);
279 int i, hCube1, hCube2;
280 Vec_IntClear( vRes );
282 if ( Fxch_TabCompare(
p, hCube1, hCube2) &&
283 Vec_IntEntry(Fxch_ManCube(
p, hCube1), Pla_CubeLit(hCube1)) == Lit0 &&
284 Vec_IntEntry(Fxch_ManCube(
p, hCube2), Pla_CubeLit(hCube2)) == Lit1 )
285 Vec_IntPushTwo( vRes, hCube1, hCube2 );
286 Vec_IntClear( vPairs );
290static inline void Fxch_CompressLiterals2(
Vec_Int_t *
p,
int iInd1,
int iInd2 )
293 assert( iInd1 >= 0 && iInd1 < Vec_IntSize(
p) );
295 assert( iInd1 >= 0 && iInd1 < Vec_IntSize(
p) );
297 if ( i != iInd1 && i != iInd2 )
298 Vec_IntWriteEntry(
p, k++, Lit );
299 Vec_IntShrink(
p, k );
301static inline void Fxch_CompressLiterals(
Vec_Int_t *
p,
int iLit1,
int iLit2 )
305 if ( Lit != iLit1 && Lit != iLit2 )
306 Vec_IntWriteEntry(
p, k++, Lit );
307 assert( Vec_IntSize(
p) == k + 2 );
308 Vec_IntShrink(
p, k );
313 int i, k, Lit, iCube, n = 0;
314 int fFound0, fFound1;
317 vCube = Vec_WecEntry( &
p->vCubes, iCube );
318 fFound0 = fFound1 = 0;
323 else if ( Lit == Lit1 )
326 if ( fFound0 && fFound1 )
327 Vec_IntWriteEntry( vCubesS, n++, Pla_CubeHandle(iCube, 255) );
329 Vec_IntShrink( vCubesS, n );
349 iDiv = Hash_Int2ManInsert(
p->vHash, Lit0, Lit1, 0 );
351 iDiv = Hash_Int2ManInsert(
p->vHash, Lit1, Lit0, 0 );
352 if ( iDiv == Vec_FltSize(&
p->vWeights) )
354 Vec_FltPush( &
p->vWeights, -2 );
355 Vec_WecPushLevel( &
p->vPairs );
356 assert( Vec_FltSize(&
p->vWeights) == Vec_WecSize(&
p->vPairs) );
358 Vec_FltAddToEntry( &
p->vWeights, iDiv, Weight );
361 if ( Vec_QueIsMember(
p->vPrio, iDiv) )
362 Vec_QueUpdate(
p->vPrio, iDiv );
364 Vec_QuePush(
p->vPrio, iDiv );
374 iDiv = *Hash_Int2ManLookup(
p->vHash, Lit0, Lit1 );
376 iDiv = *Hash_Int2ManLookup(
p->vHash, Lit1, Lit0 );
377 assert( iDiv > 0 && iDiv < Vec_FltSize(&
p->vWeights) );
378 Vec_FltAddToEntry( &
p->vWeights, iDiv, -Weight );
379 if ( Vec_QueIsMember(
p->vPrio, iDiv) )
380 Vec_QueUpdate(
p->vPrio, iDiv );
394static inline Fxch_Obj_t * Fxch_TabBin(
Fxch_Man_t *
p,
int Value ) {
return p->pBins + (Value &
p->SizeMask); }
398static inline void Fxch_TabMarkPair(
Fxch_Man_t *
p,
int i,
int j )
411static inline void Fxch_TabUnmarkPair(
Fxch_Man_t *
p,
int i,
int j )
424static inline void Fxch_TabInsertLink(
Fxch_Man_t *
p,
int i,
int j,
int fSkipCheck )
431 assert( fSkipCheck || pI->MarkN == 0 );
432 assert( fSkipCheck || pN->MarkP == 0 );
433 assert( fSkipCheck || pJ->MarkN == 0 );
434 assert( fSkipCheck || pJ->MarkP == 0 );
435 pJ->Next = pI->Next; pI->Next = j;
436 pJ->Prev = i; pN->Prev = j;
438static inline void Fxch_TabExtractLink(
Fxch_Man_t *
p,
int i,
int j )
451 pI->Next = pJ->Next; pJ->Next = 0;
452 pN->Prev = pJ->Prev; pJ->Prev = 0;
454static inline void Fxch_TabInsert(
Fxch_Man_t *
p,
int iLink,
int Value,
int hCube )
456 int iEnt, iDiv, Lit0, Lit1, fStart = 1;
460 assert( pCell->MarkN == 0 );
461 assert( pCell->MarkP == 0 );
462 assert( pCell->Cube == 0 );
464 if ( pBin->Table == 0 )
466 pBin->Table = pCell->Next = pCell->Prev = iLink;
470 for ( iEnt = pBin->Table; iEnt != (
int)pBin->Table || fStart; iEnt = pEnt->Next, fStart = 0 )
472 pEnt = Fxch_TabBin(
p, iEnt );
473 if ( pEnt->MarkN || pEnt->MarkP || !Fxch_TabCompare(
p, pEnt->Cube, hCube) )
475 Fxch_TabInsertLink(
p, iEnt, iLink, 0 );
476 Fxch_TabMarkPair(
p, iEnt, iLink );
478 Lit0 = Vec_IntEntry( Fxch_ManCube(
p, hCube), Pla_CubeLit(hCube) );
479 Lit1 = Vec_IntEntry( Fxch_ManCube(
p, pEnt->Cube), Pla_CubeLit(pEnt->Cube) );
481 iDiv =
Fxch_DivisorAdd(
p, Abc_LitNot(Lit0), Abc_LitNot(Lit1), Vec_IntSize(Fxch_ManCube(
p, hCube)) );
483 assert( iDiv < Vec_WecSize(&
p->vPairs) );
486 Vec_WecPush( &
p->vPairs, iDiv, hCube );
487 Vec_WecPush( &
p->vPairs, iDiv, pEnt->Cube );
491 Vec_WecPush( &
p->vPairs, iDiv, pEnt->Cube );
492 Vec_WecPush( &
p->vPairs, iDiv, hCube );
497 assert( iEnt == (
int)pBin->Table );
498 pEnt = Fxch_TabBin(
p, iEnt );
499 Fxch_TabInsertLink(
p, pEnt->Prev, iLink, 1 );
501static inline void Fxch_TabExtract(
Fxch_Man_t *
p,
int iLink,
int Value,
int hCube )
507 assert( pLink->Cube == hCube );
510 pPair = Fxch_TabEntry(
p, pLink->Next );
511 Fxch_TabUnmarkPair(
p, iLink, pLink->Next );
513 else if ( pLink->MarkP )
515 pPair = Fxch_TabEntry(
p, pLink->Prev );
516 Fxch_TabUnmarkPair(
p, pLink->Prev, iLink );
518 if ( (
int)pBin->Table == iLink )
519 pBin->Table = pLink->Next != iLink ? pLink->Next : 0;
520 if ( pLink->Next == iLink )
522 assert( pLink->Prev == iLink );
523 pLink->Next = pLink->Prev = 0;
526 Fxch_TabExtractLink(
p, pLink->Prev, iLink );
530 assert( Fxch_TabCompare(
p, pPair->Cube, hCube) );
532 Lit0 = Vec_IntEntry( Fxch_ManCube(
p, hCube), Pla_CubeLit(hCube) );
533 Lit1 = Vec_IntEntry( Fxch_ManCube(
p, pPair->Cube), Pla_CubeLit(pPair->Cube) );
535 Fxch_DivisorRemove(
p, Abc_LitNot(Lit0), Abc_LitNot(Lit1), Vec_IntSize(Fxch_ManCube(
p, hCube)) );
552 Vec_Int_t * vCube = Vec_WecEntry( &
p->vCubes, iCube );
554 if ( Vec_IntSize(vCube) < 2 )
565 return Vec_IntSize(vCube) * (Vec_IntSize(vCube) - 1) / 2;
569 Vec_Int_t * vCube = Vec_WecEntry( &
p->vCubes, iCube );
570 int iLinkFirst = Vec_IntEntry( &
p->vCubeLinks, iCube );
571 int k, Lit, Value = 0;
573 Value += Vec_IntEntry(&
p->vRands, Lit);
576 Value -= Vec_IntEntry(&
p->vRands, Lit);
578 Fxch_TabInsert(
p, iLinkFirst + k, Value, Pla_CubeHandle(iCube, k) );
580 Fxch_TabExtract(
p, iLinkFirst + k, Value, Pla_CubeHandle(iCube, k) );
581 Value += Vec_IntEntry(&
p->vRands, Lit);
590 p->vHash = Hash_IntManStart( 1000 );
592 for ( i = 0; i < Vec_WecSize(&
p->vCubes); i++ )
595 for ( i = 0; i < Vec_WecSize(&
p->vCubes); i++ )
598 p->vPrio = Vec_QueAlloc( Vec_FltSize(&
p->vWeights) );
599 Vec_QueSetPriority(
p->vPrio, Vec_FltArrayP(&
p->vWeights) );
602 Vec_QuePush(
p->vPrio, i );
619 Vec_Int_t * vCube1, * vCube2, * vLitP, * vLitN;
621 int i, Lit0, Lit1, hCube1, hCube2, iVarNew;
628 Lit0 = Hash_IntObjData0(
p->vHash, iDiv );
629 Lit1 = Hash_IntObjData1(
p->vHash, iDiv );
630 assert( Lit0 >= 0 && Lit1 >= 0 && Lit0 < Lit1 );
631 Vec_WrdPush( &
p->vDivs, ((
word)Lit1 << 32) | (
word)Lit0 );
639 vLitP = Vec_WecEntry(&
p->vLits, Lit0);
640 vLitN = Vec_WecEntry(&
p->vLits, Lit1);
641 Fxch_CompressCubes(
p, vLitP );
642 Fxch_CompressCubes(
p, vLitN );
645 Vec_IntTwoRemoveCommon( vLitP, vLitN, &
p->vCubesS );
646 Fxch_FilterCubes(
p, &
p->vCubesS, Lit0, Lit1 );
649 Fxch_CollectDoubles(
p, Vec_WecEntry(&
p->vPairs, iDiv), &
p->vCubesD, Abc_LitNot(Lit0), Abc_LitNot(Lit1) );
650 assert( Vec_IntSize(&
p->vCubesD) % 2 == 0 );
651 Vec_IntUniqifyPairs( &
p->vCubesD );
652 assert( Vec_IntSize(&
p->vCubesD) % 2 == 0 );
682 iVarNew = Vec_WecSize( &
p->vLits ) / 2;
683 vLitP = Vec_WecPushLevel( &
p->vLits );
684 vLitN = Vec_WecPushLevel( &
p->vLits );
685 vLitP = Vec_WecEntry( &
p->vLits, Vec_WecSize(&
p->vLits) - 2 );
691 vCube1 = Fxch_ManCube(
p, hCube1 );
697 Fxch_CompressLiterals( vCube1, Lit0, Lit1 );
699 Vec_IntPush( vLitP, Pla_CubeNum(hCube1) );
700 Vec_IntPush( vCube1, Abc_Var2Lit(iVarNew, 0) );
710 vCube1 = Fxch_ManCube(
p, hCube1 );
711 vCube2 = Fxch_ManCube(
p, hCube2 );
712 assert( Vec_IntEntry(vCube1, Pla_CubeLit(hCube1)) == Abc_LitNot(Lit0) );
713 assert( Vec_IntEntry(vCube2, Pla_CubeLit(hCube2)) == Abc_LitNot(Lit1) );
714 Fxch_CompressLiterals2( vCube1, Pla_CubeLit(hCube1), -1 );
716 Vec_IntPush( vLitN, Pla_CubeNum(hCube1) );
717 Vec_IntPush( vCube1, Abc_Var2Lit(iVarNew, 1) );
718 p->nLits -= Vec_IntSize(vCube2);
724 Vec_IntClear( vCube2 );
726 Vec_IntSort( vLitN, 0 );
727 Vec_IntSort( vLitP, 0 );
760 printf(
"Num =%6d ", Vec_WrdSize(&
p->vDivs) -
p->nVars );
761 printf(
"Cubes =%8d ", Vec_WecSizeUsed(&
p->vCubes) );
762 printf(
"Lits =%8d ",
p->nLits );
763 printf(
"Divs =%8d ", Hash_IntManEntryNum(
p->vHash) );
764 printf(
"Divs+ =%8d ", Vec_QueSize(
p->vPrio) );
765 printf(
"PairS =%6d ",
p->nPairsS );
766 printf(
"PairD =%6d ",
p->nPairsD );
767 Abc_PrintTime( 1,
"Time", clk );
770static inline void Fxch_PrintDivOne(
Fxch_Man_t *
p,
int iDiv )
773 int Lit0 = Hash_IntObjData0(
p->vHash, iDiv );
774 int Lit1 = Hash_IntObjData1(
p->vHash, iDiv );
775 assert( Lit0 >= 0 && Lit1 >= 0 && Lit0 < Lit1 );
776 printf(
"Div %4d : ", iDiv );
777 printf(
"Weight %12.5f ", Vec_FltEntry(&
p->vWeights, iDiv) );
778 printf(
"Pairs = %5d ", Vec_IntSize(Vec_WecEntry(&
p->vPairs, iDiv))/2 );
779 for ( i = 0; i < Vec_WrdSize(&
p->vDivs); i++ )
781 if ( i == Abc_Lit2Var(Lit0) )
782 printf(
"%d", !Abc_LitIsCompl(Lit0) );
783 else if ( i == Abc_Lit2Var(Lit1) )
784 printf(
"%d", !Abc_LitIsCompl(Lit1) );
793 for ( iDiv = 1; iDiv < Vec_FltSize(&
p->vWeights); iDiv++ )
794 Fxch_PrintDivOne(
p, iDiv );
806 Fxch_PrintStats(
p, Abc_Clock() - clk );
807 p->timeStart = Abc_Clock();
808 for ( i = 0; i < nNewNodesMax && Vec_QueTopPriority(
p->vPrio) > 0.0; i++ )
810 iDiv = Vec_QuePop(
p->vPrio);
814 Fxch_PrintDivOne(
p, iDiv );
818 Fxch_PrintStats(
p, Abc_Clock() - clk );
835 char pFileName[1000];
839 Vec_WecZero( &
p->vCubeLits );
840 Vec_WecZero( &
p->vOccurs );
842 sprintf( pFileName,
"%s.blif", Pla_ManName(
p) );
#define ABC_INFINITY
MACRO DEFINITIONS ///.
#define ABC_CALLOC(type, num)
#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
unsigned Gia_ManRandom(int fReset)
FUNCTION DEFINITIONS ///.
unsigned __int64 word
DECLARATIONS ///.
void Fxch_ManStop(Fxch_Man_t *p)
int Fxch_TabDoubleDivisors(Fxch_Man_t *p, int iCube, int fAdd)
int Pla_ManPerformFxch(Pla_Man_t *p)
void Fxch_DivisorRemove(Fxch_Man_t *p, int Lit0, int Lit1, int Weight)
int Fxch_ManFastExtract(Fxch_Man_t *p, int fVerbose, int fVeryVerbose)
typedefABC_NAMESPACE_IMPL_START struct Fxch_Obj_t_ Fxch_Obj_t
DECLARATIONS ///.
void Fxch_ManWriteBlif(char *pFileName, Vec_Wec_t *vCubes, Vec_Wrd_t *vDivs)
FUNCTION DEFINITIONS ///.
struct Fxch_Man_t_ Fxch_Man_t
TYPEDEF DECLARATIONS ///.
void Fxch_ManCreateDivisors(Fxch_Man_t *p)
int Fxch_DivisorAdd(Fxch_Man_t *p, int Lit0, int Lit1, int Weight)
int Fxch_TabSingleDivisors(Fxch_Man_t *p, int iCube, int fAdd)
Fxch_Man_t * Fxch_ManStart(Vec_Wec_t *vCubes, Vec_Wec_t *vLits)
void Fxch_ManUpdate(Fxch_Man_t *p, int iDiv)
void Pla_ManConvertFromBits(Pla_Man_t *p)
struct Pla_Man_t_ Pla_Man_t
#define Vec_FltForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
typedefABC_NAMESPACE_HEADER_START struct Vec_Flt_t_ Vec_Flt_t
INCLUDES ///.
struct Hash_IntMan_t_ Hash_IntMan_t
#define Vec_IntForEachEntryDouble(vVec, Entry1, Entry2, i)
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
#define Vec_IntForEachEntryStart(vVec, Entry, i, Start)
typedefABC_NAMESPACE_HEADER_START struct Vec_Que_t_ Vec_Que_t
INCLUDES ///.
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
#define Vec_WrdForEachEntryStart(vVec, Entry, i, Start)
typedefABC_NAMESPACE_HEADER_START struct Vec_Wrd_t_ Vec_Wrd_t
INCLUDES ///.