ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
giaOf.c
Go to the documentation of this file.
1
20
21#include "gia.h"
22#include "misc/st/st.h"
23#include "map/mio/mio.h"
24#include "misc/util/utilTruth.h"
25#include "misc/extra/extra.h"
26#include "base/main/main.h"
27#include "misc/vec/vecMem.h"
28#include "misc/vec/vecWec.h"
29#include "opt/dau/dau.h"
30#include "sat/bsat/satStore.h"
31
33
37
38#define OF_LEAF_MAX 6
39#define OF_CUT_MAX 32
40#define OF_NO_LEAF 31
41#define OF_NO_FUNC 0x7FFFFFF
42#define OF_CUT_EXTRA 4 // size; delay1, delay2; area
43
44typedef struct Of_Cut_t_ Of_Cut_t;
46{
47 word Sign; // signature
48 int Delay; // delay
49 int Flow; // flow
50 unsigned iFunc : 27; // function (OF_NO_FUNC)
51 unsigned nLeaves : 5; // leaf number (OF_NO_LEAF)
52 int pLeaves[OF_LEAF_MAX+1]; // leaves
53};
54typedef struct Of_Obj_t_ Of_Obj_t;
56{
57 int iCutH; // best cut
58 int iCutH2; // best cut
59 int Delay1; // arrival time
60 int Delay2; // arrival time
61 int Required; // required
62 int nRefs; // references
63 int Flow; // area flow
64 int Temp; // unused
65};
66typedef struct Of_Man_t_ Of_Man_t;
68{
69 // user data
70 Gia_Man_t * pGia; // derived manager
71 Jf_Par_t * pPars; // parameters
72 // cut data
73 Vec_Mem_t * vTtMem; // truth tables
74 Vec_Ptr_t vPages; // cut memory
75 Vec_Int_t vCutSets; // cut offsets
76 Vec_Int_t vCutFlows; // temporary cut area
77 Vec_Int_t vCutDelays; // temporary cut delay
78 Vec_Int_t vCutRefs; // temporary cut referebces
79 int iCur; // current position
80 int Iter; // mapping iterations
81 // object data
83 // statistics
84 abctime clkStart; // starting time
85 double CutCount[6]; // cut counts
86};
87
88#define OF_NUM 10
89#define OF_NUMINV 0.1
90
91static inline int Of_Flt2Int( float f ) { return (int)(OF_NUM*f); }
92static inline float Of_Int2Flt( int i ) { return OF_NUMINV*i; }
93
94static inline int * Of_ManCutSet( Of_Man_t * p, int i ) { return (int *)Vec_PtrEntry(&p->vPages, i >> 16) + (i & 0xFFFF); }
95static inline int Of_ObjCutSetId( Of_Man_t * p, int i ) { return Vec_IntEntry( &p->vCutSets, i ); }
96static inline int * Of_ObjCutSet( Of_Man_t * p, int i ) { return Of_ManCutSet(p, Of_ObjCutSetId(p, i)); }
97static inline int Of_ObjHasCuts( Of_Man_t * p, int i ) { return (int)(Vec_IntEntry(&p->vCutSets, i) > 0); }
98
99static inline int Of_ObjCutFlow( Of_Man_t * p, int i ) { return Vec_IntEntry(&p->vCutFlows, i); }
100static inline int Of_ObjCutDelay( Of_Man_t * p, int i ) { return Vec_IntEntry(&p->vCutDelays, i); }
101static inline void Of_ObjSetCutFlow( Of_Man_t * p, int i, int a ) { Vec_IntWriteEntry(&p->vCutFlows, i, a); }
102static inline void Of_ObjSetCutDelay( Of_Man_t * p, int i, int d ) { Vec_IntWriteEntry(&p->vCutDelays, i, d); }
103
104static inline int Of_CutSize( int * pCut ) { return pCut[0] & OF_NO_LEAF; }
105static inline int Of_CutFunc( int * pCut ) { return ((unsigned)pCut[0] >> 5); }
106static inline int * Of_CutLeaves( int * pCut ) { return pCut + 1; }
107static inline int Of_CutSetBoth( int n, int f ) { return n | (f << 5); }
108static inline int Of_CutHandle( int * pCutSet, int * pCut ) { assert( pCut > pCutSet ); return pCut - pCutSet; }
109static inline int * Of_CutFromHandle( int * pCutSet, int h ) { assert( h > 0 ); return pCutSet + h; }
110
111static inline int Of_CutDelay1( int * pCut ) { return pCut[1 + Of_CutSize(pCut)]; }
112static inline int Of_CutDelay2( int * pCut ) { return pCut[2 + Of_CutSize(pCut)]; }
113static inline int Of_CutAreaFlow( int * pCut ) { return pCut[3 + Of_CutSize(pCut)]; }
114static inline void Of_CutSetDelay1( int * pCut, int d ) { pCut[1 + Of_CutSize(pCut)] = d; }
115static inline void Of_CutSetDelay2( int * pCut, int d ) { pCut[2 + Of_CutSize(pCut)] = d; }
116static inline void Of_CutSetAreaFlow( int * pCut, int d ) { pCut[3 + Of_CutSize(pCut)] = d; }
117
118static inline int Of_CutVar( int * pCut, int v ) { return Abc_Lit2Var(Of_CutLeaves(pCut)[v]); }
119static inline int Of_CutFlag( int * pCut, int v ) { return Abc_LitIsCompl(Of_CutLeaves(pCut)[v]); }
120static inline void Of_CutCleanFlag( int * pCut, int v ) { Of_CutLeaves(pCut)[v] = Abc_LitRegular(Of_CutLeaves(pCut)[v]); }
121static inline void Of_CutSetFlag( int * pCut, int v, int x ) { Of_CutLeaves(pCut)[v] = Abc_Var2Lit(Of_CutVar(pCut, v), x); }
122
123static inline Of_Obj_t * Of_ObjData( Of_Man_t * p, int i ) { return p->pObjs + i; }
124
125static inline int Of_ObjCutBest( Of_Man_t * p, int i ) { return Of_ObjData(p, i)->iCutH; }
126static inline int Of_ObjCutBest2( Of_Man_t * p, int i ) { return Of_ObjData(p, i)->iCutH2; }
127static inline int Of_ObjDelay1( Of_Man_t * p, int i ) { return Of_ObjData(p, i)->Delay1; }
128static inline int Of_ObjDelay2( Of_Man_t * p, int i ) { return Of_ObjData(p, i)->Delay2; }
129static inline int Of_ObjRequired( Of_Man_t * p, int i ) { return Of_ObjData(p, i)->Required; }
130static inline int Of_ObjRefNum( Of_Man_t * p, int i ) { return Of_ObjData(p, i)->nRefs; }
131static inline int Of_ObjFlow( Of_Man_t * p, int i ) { return Of_ObjData(p, i)->Flow; }
132
133static inline void Of_ObjSetCutBest( Of_Man_t * p, int i, int x ) { Of_ObjData(p, i)->iCutH = x; }
134static inline void Of_ObjSetCutBest2( Of_Man_t * p, int i, int x ) { Of_ObjData(p, i)->iCutH2 = x; }
135static inline void Of_ObjSetDelay1( Of_Man_t * p, int i, int x ) { Of_ObjData(p, i)->Delay1 = x; }
136static inline void Of_ObjSetDelay2( Of_Man_t * p, int i, int x ) { Of_ObjData(p, i)->Delay2 = x; }
137static inline void Of_ObjSetRequired( Of_Man_t * p, int i, int x ) { Of_ObjData(p, i)->Required = x; }
138static inline void Of_ObjSetRefNum( Of_Man_t * p, int i, int x ) { Of_ObjData(p, i)->nRefs = x; }
139static inline void Of_ObjSetFlow( Of_Man_t * p, int i, int x ) { Of_ObjData(p, i)->Flow = x; }
140static inline void Of_ObjUpdateRequired( Of_Man_t * p,int i, int x ) { if ( Of_ObjRequired(p, i) > x ) Of_ObjSetRequired(p, i, x); }
141static inline int Of_ObjRefInc( Of_Man_t * p, int i ) { return Of_ObjData(p, i)->nRefs++; }
142static inline int Of_ObjRefDec( Of_Man_t * p, int i ) { return --Of_ObjData(p, i)->nRefs; }
143
144static inline int * Of_ObjCutBestP( Of_Man_t * p, int iObj ) { assert(iObj>0 && iObj<Gia_ManObjNum(p->pGia));return Of_ManCutSet( p, Of_ObjCutBest(p, iObj) ); }
145static inline void Of_ObjSetCutBestP( Of_Man_t * p, int * pCutSet, int iObj, int * pCut ) { Of_ObjSetCutBest( p, iObj, Of_ObjCutSetId(p, iObj) + Of_CutHandle(pCutSet, pCut) ); }
146
147static inline int * Of_ObjCutBestP2( Of_Man_t * p, int iObj ) { assert(iObj>0 && iObj<Gia_ManObjNum(p->pGia));return Of_ManCutSet( p, Of_ObjCutBest2(p, iObj) ); }
148static inline void Of_ObjSetCutBestP2( Of_Man_t * p, int * pCutSet, int iObj, int * pCut ) { Of_ObjSetCutBest2( p, iObj, Of_ObjCutSetId(p, iObj) + Of_CutHandle(pCutSet, pCut) ); }
149
150#define Of_SetForEachCut( pList, pCut, i ) for ( i = 0, pCut = pList + 1; i < pList[0]; i++, pCut += Of_CutSize(pCut) + OF_CUT_EXTRA )
151#define Of_ObjForEachCut( pCuts, i, nCuts ) for ( i = 0, i < nCuts; i++ )
152#define Of_CutForEachVar( pCut, iVar, i ) for ( i = 0; i < Of_CutSize(pCut) && (iVar = Of_CutVar(pCut,i)); i++ )
153#define Of_CutForEachVarFlag( pCut, iVar, Flag, i ) for ( i = 0; i < Of_CutSize(pCut) && (iVar = Of_CutVar(pCut,i)) && ((Flag = Of_CutFlag(pCut,i)), 1); i++ )
154
158
171{
172 int AreaUnit = 1000;
173 int i, Id, Total = 0;
174 Gia_Obj_t * pObj;
175 assert( p->pGia->pRefs == NULL );
176 Gia_ManCreateRefs( p->pGia );
177 Of_ObjSetFlow( p, 0, 0 );
178 Gia_ManForEachCiId( p->pGia, Id, i )
179 Of_ObjSetFlow( p, Id, 0 );
180 Gia_ManForEachAnd( p->pGia, pObj, Id )
181 Of_ObjSetFlow( p, Id, (Gia_ObjFanin0(pObj)->Value + Gia_ObjFanin1(pObj)->Value + AreaUnit) / Gia_ObjRefNum(p->pGia, pObj) );
182 Gia_ManForEachCo( p->pGia, pObj, i )
183 Total += Gia_ObjFanin0(pObj)->Value;
184 ABC_FREE( p->pGia->pRefs );
185 if ( 1 )
186 return;
187 printf( "CI = %5d. ", Gia_ManCiNum(p->pGia) );
188 printf( "CO = %5d. ", Gia_ManCoNum(p->pGia) );
189 printf( "And = %8d. ", Gia_ManAndNum(p->pGia) );
190 printf( "Area = %8d. ", Total/AreaUnit );
191 printf( "\n" );
192}
193
206{
207 extern void Mf_ManSetFlowRefs( Gia_Man_t * p, Vec_Int_t * vRefs );
208 Of_Man_t * p;
209 Vec_Int_t * vFlowRefs;
210 int * pRefs = NULL;
211 assert( pPars->nCutNum > 1 && pPars->nCutNum <= OF_CUT_MAX );
212 assert( pPars->nLutSize > 1 && pPars->nLutSize <= OF_LEAF_MAX );
213 ABC_FREE( pGia->pRefs );
214 Vec_IntFreeP( &pGia->vCellMapping );
215 if ( Gia_ManHasChoices(pGia) )
216 Gia_ManSetPhase(pGia);
217 // create references
218 ABC_FREE( pGia->pRefs );
219 vFlowRefs = Vec_IntAlloc(0);
220 Mf_ManSetFlowRefs( pGia, vFlowRefs );
221 pGia->pRefs= Vec_IntReleaseArray(vFlowRefs);
222 Vec_IntFree(vFlowRefs);
223 // create
224 p = ABC_CALLOC( Of_Man_t, 1 );
225 p->clkStart = Abc_Clock();
226 p->pGia = pGia;
227 p->pPars = pPars;
228 p->pObjs = ABC_CALLOC( Of_Obj_t, Gia_ManObjNum(pGia) );
229 p->iCur = 2;
230 // other
231 Vec_PtrGrow( &p->vPages, 256 ); // cut memory
232 Vec_IntFill( &p->vCutSets, Gia_ManObjNum(pGia), 0 ); // cut offsets
233 Vec_IntFill( &p->vCutFlows, Gia_ManObjNum(pGia), 0 ); // cut area
234 Vec_IntFill( &p->vCutDelays,Gia_ManObjNum(pGia), 0 ); // cut delay
235 Vec_IntGrow( &p->vCutRefs, 1000 ); // cut references
236 if ( pPars->fCutMin )
237 p->vTtMem = Vec_MemAllocForTT( 6, 0 );
238 // compute area flow
239 pRefs = pGia->pRefs; pGia->pRefs = NULL;
240 Of_ManAreaFlow( p );
241 pGia->pRefs = pRefs;
242 return p;
243}
245{
246 Vec_PtrFreeData( &p->vPages );
247 Vec_PtrErase( &p->vPages );
248 Vec_IntErase( &p->vCutSets );
249 Vec_IntErase( &p->vCutFlows );
250 Vec_IntErase( &p->vCutDelays );
251 Vec_IntErase( &p->vCutRefs );
252 ABC_FREE( p->pObjs );
253 // matching
254 if ( p->pPars->fCutMin )
255 Vec_MemHashFree( p->vTtMem );
256 if ( p->pPars->fCutMin )
257 Vec_MemFree( p->vTtMem );
258 ABC_FREE( p );
259}
260
261
262
263
275static inline int Of_CutComputeTruth6( Of_Man_t * p, Of_Cut_t * pCut0, Of_Cut_t * pCut1, int fCompl0, int fCompl1, Of_Cut_t * pCutR, int fIsXor )
276{
277// extern int Of_ManTruthCanonicize( word * t, int nVars );
278 int nOldSupp = pCutR->nLeaves, truthId, fCompl; word t;
279 word t0 = *Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut0->iFunc));
280 word t1 = *Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut1->iFunc));
281 if ( Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ) t0 = ~t0;
282 if ( Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ) t1 = ~t1;
283 t0 = Abc_Tt6Expand( t0, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
284 t1 = Abc_Tt6Expand( t1, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
285 t = fIsXor ? t0 ^ t1 : t0 & t1;
286 if ( (fCompl = (int)(t & 1)) ) t = ~t;
287 pCutR->nLeaves = Abc_Tt6MinBase( &t, pCutR->pLeaves, pCutR->nLeaves );
288 assert( (int)(t & 1) == 0 );
289 truthId = Vec_MemHashInsert(p->vTtMem, &t);
290 pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
291 assert( (int)pCutR->nLeaves <= nOldSupp );
292 return (int)pCutR->nLeaves < nOldSupp;
293}
294static inline int Of_CutComputeTruthMux6( Of_Man_t * p, Of_Cut_t * pCut0, Of_Cut_t * pCut1, Of_Cut_t * pCutC, int fCompl0, int fCompl1, int fComplC, Of_Cut_t * pCutR )
295{
296 int nOldSupp = pCutR->nLeaves, truthId, fCompl; word t;
297 word t0 = *Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut0->iFunc));
298 word t1 = *Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut1->iFunc));
299 word tC = *Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCutC->iFunc));
300 if ( Abc_LitIsCompl(pCut0->iFunc) ^ fCompl0 ) t0 = ~t0;
301 if ( Abc_LitIsCompl(pCut1->iFunc) ^ fCompl1 ) t1 = ~t1;
302 if ( Abc_LitIsCompl(pCutC->iFunc) ^ fComplC ) tC = ~tC;
303 t0 = Abc_Tt6Expand( t0, pCut0->pLeaves, pCut0->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
304 t1 = Abc_Tt6Expand( t1, pCut1->pLeaves, pCut1->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
305 tC = Abc_Tt6Expand( tC, pCutC->pLeaves, pCutC->nLeaves, pCutR->pLeaves, pCutR->nLeaves );
306 t = (tC & t1) | (~tC & t0);
307 if ( (fCompl = (int)(t & 1)) ) t = ~t;
308 pCutR->nLeaves = Abc_Tt6MinBase( &t, pCutR->pLeaves, pCutR->nLeaves );
309 assert( (int)(t & 1) == 0 );
310 truthId = Vec_MemHashInsert(p->vTtMem, &t);
311 pCutR->iFunc = Abc_Var2Lit( truthId, fCompl );
312 assert( (int)pCutR->nLeaves <= nOldSupp );
313 return (int)pCutR->nLeaves < nOldSupp;
314}
315
316
328static inline int Of_CutCountBits( word i )
329{
330 i = i - ((i >> 1) & 0x5555555555555555);
331 i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333);
332 i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F);
333 return (i*(0x0101010101010101))>>56;
334}
335static inline word Of_CutGetSign( int * pLeaves, int nLeaves )
336{
337 word Sign = 0; int i;
338 for ( i = 0; i < nLeaves; i++ )
339 Sign |= ((word)1) << (pLeaves[i] & 0x3F);
340 return Sign;
341}
342static inline int Of_CutCreateUnit( Of_Cut_t * p, int i )
343{
344 p->Delay = 0;
345 p->Flow = 0;
346 p->iFunc = 2;
347 p->nLeaves = 1;
348 p->pLeaves[0] = i;
349 p->Sign = ((word)1) << (i & 0x3F);
350 return 1;
351}
352static inline void Of_Cutprintf( Of_Man_t * p, Of_Cut_t * pCut )
353{
354 int i, nDigits = Abc_Base10Log(Gia_ManObjNum(p->pGia));
355 printf( "%d {", pCut->nLeaves );
356 for ( i = 0; i < (int)pCut->nLeaves; i++ )
357 printf( " %*d", nDigits, pCut->pLeaves[i] );
358 for ( ; i < (int)p->pPars->nLutSize; i++ )
359 printf( " %*s", nDigits, " " );
360 printf( " } D = %4d A = %9d F = %6d ",
361 pCut->Delay, pCut->Flow, pCut->iFunc );
362 if ( p->vTtMem )
363 Dau_DsdPrintFromTruth( Vec_MemReadEntry(p->vTtMem, Abc_Lit2Var(pCut->iFunc)), pCut->nLeaves );
364 else
365 printf( "\n" );
366}
367static inline int Of_ManPrepareCuts( Of_Cut_t * pCuts, Of_Man_t * p, int iObj, int fAddUnit )
368{
369 if ( Of_ObjHasCuts(p, iObj) )
370 {
371 Of_Cut_t * pMfCut = pCuts;
372 int i, * pCut, * pList = Of_ObjCutSet(p, iObj);
373 Of_SetForEachCut( pList, pCut, i )
374 {
375 pMfCut->Delay = 0;
376 pMfCut->Flow = 0;
377 pMfCut->iFunc = Of_CutFunc( pCut );
378 pMfCut->nLeaves = Of_CutSize( pCut );
379 pMfCut->Sign = Of_CutGetSign( pCut+1, Of_CutSize(pCut) );
380 memcpy( pMfCut->pLeaves, pCut+1, sizeof(int) * Of_CutSize(pCut) );
381 pMfCut++;
382 }
383 if ( fAddUnit && pCuts->nLeaves > 1 )
384 return pList[0] + Of_CutCreateUnit( pMfCut, iObj );
385 return pList[0];
386 }
387 return Of_CutCreateUnit( pCuts, iObj );
388}
389static inline int Of_ManSaveCuts( Of_Man_t * p, Of_Cut_t ** pCuts, int nCuts )
390{
391 int i, * pPlace, iCur, nInts = 1, nCutsNew = 0;
392 for ( i = 0; i < nCuts; i++ )
393 nInts += pCuts[i]->nLeaves + OF_CUT_EXTRA, nCutsNew++;
394 if ( (p->iCur & 0xFFFF) + nInts > 0xFFFF )
395 p->iCur = ((p->iCur >> 16) + 1) << 16;
396 if ( Vec_PtrSize(&p->vPages) == (p->iCur >> 16) )
397 Vec_PtrPush( &p->vPages, ABC_CALLOC(int, (1<<16)) );
398 iCur = p->iCur; p->iCur += nInts;
399 pPlace = Of_ManCutSet( p, iCur );
400 *pPlace++ = nCutsNew;
401 for ( i = 0; i < nCuts; i++ )
402 {
403 *pPlace++ = Of_CutSetBoth( pCuts[i]->nLeaves, pCuts[i]->iFunc );
404 memcpy( pPlace, pCuts[i]->pLeaves, sizeof(int) * pCuts[i]->nLeaves );
405 pPlace += pCuts[i]->nLeaves;
406 memset( pPlace, 0xFF, sizeof(int) * (OF_CUT_EXTRA - 1) );
407 pPlace += OF_CUT_EXTRA - 1;
408 }
409 return iCur;
410}
411static inline void Of_ManLiftCuts( Of_Man_t * p, int iObj )
412{
413 int i, k, * pCut, * pList = Of_ObjCutSet(p, iObj);
414 assert( Of_ObjHasCuts(p, iObj) );
415 Of_SetForEachCut( pList, pCut, i )
416 {
417 for ( k = 1; k <= Of_CutSize(pCut); k++ )
418 pCut[k] = Abc_Var2Lit(pCut[k], 0);
419 }
420}
421static inline void Of_CutPrint( int * pCut )
422{
423 int k, iVar;
424 printf( "Cut with %d inputs and function %3d : { ", Of_CutSize(pCut), Of_CutFunc(pCut) == OF_NO_FUNC ? 0 : Of_CutFunc(pCut) );
425 Of_CutForEachVar( pCut, iVar, k )
426 printf( "%d ", iVar );
427 printf( "}\n" );
428}
429
441static inline int Of_CutCheck( Of_Cut_t * pBase, Of_Cut_t * pCut ) // check if pCut is contained in pBase
442{
443 int nSizeB = pBase->nLeaves;
444 int nSizeC = pCut->nLeaves;
445 int i, * pB = pBase->pLeaves;
446 int k, * pC = pCut->pLeaves;
447 for ( i = 0; i < nSizeC; i++ )
448 {
449 for ( k = 0; k < nSizeB; k++ )
450 if ( pC[i] == pB[k] )
451 break;
452 if ( k == nSizeB )
453 return 0;
454 }
455 return 1;
456}
457static inline int Of_SetCheckArray( Of_Cut_t ** ppCuts, int nCuts )
458{
459 Of_Cut_t * pCut0, * pCut1;
460 int i, k, m, n, Value;
461 assert( nCuts > 0 );
462 for ( i = 0; i < nCuts; i++ )
463 {
464 pCut0 = ppCuts[i];
465 assert( pCut0->nLeaves <= OF_LEAF_MAX );
466 assert( pCut0->Sign == Of_CutGetSign(pCut0->pLeaves, pCut0->nLeaves) );
467 // check duplicates
468 for ( m = 0; m < (int)pCut0->nLeaves; m++ )
469 for ( n = m + 1; n < (int)pCut0->nLeaves; n++ )
470 assert( pCut0->pLeaves[m] < pCut0->pLeaves[n] );
471 // check pairs
472 for ( k = 0; k < nCuts; k++ )
473 {
474 pCut1 = ppCuts[k];
475 if ( pCut0 == pCut1 )
476 continue;
477 // check containments
478 Value = Of_CutCheck( pCut0, pCut1 );
479 assert( Value == 0 );
480 }
481 }
482 return 1;
483}
484
485
497static inline int Of_CutMergeOrder( Of_Cut_t * pCut0, Of_Cut_t * pCut1, Of_Cut_t * pCut, int nLutSize )
498{
499 int nSize0 = pCut0->nLeaves;
500 int nSize1 = pCut1->nLeaves;
501 int i, * pC0 = pCut0->pLeaves;
502 int k, * pC1 = pCut1->pLeaves;
503 int c, * pC = pCut->pLeaves;
504 // the case of the largest cut sizes
505 if ( nSize0 == nLutSize && nSize1 == nLutSize )
506 {
507 for ( i = 0; i < nSize0; i++ )
508 {
509 if ( pC0[i] != pC1[i] ) return 0;
510 pC[i] = pC0[i];
511 }
512 pCut->nLeaves = nLutSize;
513 pCut->iFunc = OF_NO_FUNC;
514 pCut->Sign = pCut0->Sign | pCut1->Sign;
515 return 1;
516 }
517 // compare two cuts with different numbers
518 i = k = c = 0;
519 if ( nSize0 == 0 ) goto FlushCut1;
520 if ( nSize1 == 0 ) goto FlushCut0;
521 while ( 1 )
522 {
523 if ( c == nLutSize ) return 0;
524 if ( pC0[i] < pC1[k] )
525 {
526 pC[c++] = pC0[i++];
527 if ( i >= nSize0 ) goto FlushCut1;
528 }
529 else if ( pC0[i] > pC1[k] )
530 {
531 pC[c++] = pC1[k++];
532 if ( k >= nSize1 ) goto FlushCut0;
533 }
534 else
535 {
536 pC[c++] = pC0[i++]; k++;
537 if ( i >= nSize0 ) goto FlushCut1;
538 if ( k >= nSize1 ) goto FlushCut0;
539 }
540 }
541
542FlushCut0:
543 if ( c + nSize0 > nLutSize + i ) return 0;
544 while ( i < nSize0 )
545 pC[c++] = pC0[i++];
546 pCut->nLeaves = c;
547 pCut->iFunc = OF_NO_FUNC;
548 pCut->Sign = pCut0->Sign | pCut1->Sign;
549 return 1;
550
551FlushCut1:
552 if ( c + nSize1 > nLutSize + k ) return 0;
553 while ( k < nSize1 )
554 pC[c++] = pC1[k++];
555 pCut->nLeaves = c;
556 pCut->iFunc = OF_NO_FUNC;
557 pCut->Sign = pCut0->Sign | pCut1->Sign;
558 return 1;
559}
560static inline int Of_CutMergeOrderMux( Of_Cut_t * pCut0, Of_Cut_t * pCut1, Of_Cut_t * pCut2, Of_Cut_t * pCut, int nLutSize )
561{
562 int x0, i0 = 0, nSize0 = pCut0->nLeaves, * pC0 = pCut0->pLeaves;
563 int x1, i1 = 0, nSize1 = pCut1->nLeaves, * pC1 = pCut1->pLeaves;
564 int x2, i2 = 0, nSize2 = pCut2->nLeaves, * pC2 = pCut2->pLeaves;
565 int xMin, c = 0, * pC = pCut->pLeaves;
566 while ( 1 )
567 {
568 x0 = (i0 == nSize0) ? ABC_INFINITY : pC0[i0];
569 x1 = (i1 == nSize1) ? ABC_INFINITY : pC1[i1];
570 x2 = (i2 == nSize2) ? ABC_INFINITY : pC2[i2];
571 xMin = Abc_MinInt( Abc_MinInt(x0, x1), x2 );
572 if ( xMin == ABC_INFINITY ) break;
573 if ( c == nLutSize ) return 0;
574 pC[c++] = xMin;
575 if (x0 == xMin) i0++;
576 if (x1 == xMin) i1++;
577 if (x2 == xMin) i2++;
578 }
579 pCut->nLeaves = c;
580 pCut->iFunc = OF_NO_FUNC;
581 pCut->Sign = pCut0->Sign | pCut1->Sign | pCut2->Sign;
582 return 1;
583}
584static inline int Of_SetCutIsContainedOrder( Of_Cut_t * pBase, Of_Cut_t * pCut ) // check if pCut is contained in pBase
585{
586 int i, nSizeB = pBase->nLeaves;
587 int k, nSizeC = pCut->nLeaves;
588 if ( nSizeB == nSizeC )
589 {
590 for ( i = 0; i < nSizeB; i++ )
591 if ( pBase->pLeaves[i] != pCut->pLeaves[i] )
592 return 0;
593 return 1;
594 }
595 assert( nSizeB > nSizeC );
596 if ( nSizeC == 0 )
597 return 1;
598 for ( i = k = 0; i < nSizeB; i++ )
599 {
600 if ( pBase->pLeaves[i] > pCut->pLeaves[k] )
601 return 0;
602 if ( pBase->pLeaves[i] == pCut->pLeaves[k] )
603 {
604 if ( ++k == nSizeC )
605 return 1;
606 }
607 }
608 return 0;
609}
610static inline int Of_SetLastCutIsContained( Of_Cut_t ** pCuts, int nCuts )
611{
612 int i;
613 for ( i = 0; i < nCuts; i++ )
614 if ( pCuts[i]->nLeaves <= pCuts[nCuts]->nLeaves && (pCuts[i]->Sign & pCuts[nCuts]->Sign) == pCuts[i]->Sign && Of_SetCutIsContainedOrder(pCuts[nCuts], pCuts[i]) )
615 return 1;
616 return 0;
617}
618static inline int Of_SetLastCutContainsArea( Of_Cut_t ** pCuts, int nCuts )
619{
620 int i, k, fChanges = 0;
621 for ( i = 0; i < nCuts; i++ )
622 if ( pCuts[nCuts]->nLeaves < pCuts[i]->nLeaves && (pCuts[nCuts]->Sign & pCuts[i]->Sign) == pCuts[nCuts]->Sign && Of_SetCutIsContainedOrder(pCuts[i], pCuts[nCuts]) )
623 pCuts[i]->nLeaves = OF_NO_LEAF, fChanges = 1;
624 if ( !fChanges )
625 return nCuts;
626 for ( i = k = 0; i <= nCuts; i++ )
627 {
628 if ( pCuts[i]->nLeaves == OF_NO_LEAF )
629 continue;
630 if ( k < i )
631 ABC_SWAP( Of_Cut_t *, pCuts[k], pCuts[i] );
632 k++;
633 }
634 return k - 1;
635}
636static inline int Of_CutCompareArea( Of_Cut_t * pCut0, Of_Cut_t * pCut1 )
637{
638 if ( pCut0->Delay < pCut1->Delay ) return -1;
639 if ( pCut0->Delay > pCut1->Delay ) return 1;
640 if ( pCut0->Flow < pCut1->Flow ) return -1;
641 if ( pCut0->Flow > pCut1->Flow ) return 1;
642 if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
643 if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
644 return 0;
645}
646static inline void Of_SetSortByArea( Of_Cut_t ** pCuts, int nCuts )
647{
648 int i;
649 for ( i = nCuts; i > 0; i-- )
650 {
651 if ( Of_CutCompareArea(pCuts[i - 1], pCuts[i]) < 0 )
652 return;
653 ABC_SWAP( Of_Cut_t *, pCuts[i - 1], pCuts[i] );
654 }
655}
656static inline int Of_SetAddCut( Of_Cut_t ** pCuts, int nCuts, int nCutNum )
657{
658 if ( nCuts == 0 )
659 return 1;
660 nCuts = Of_SetLastCutContainsArea(pCuts, nCuts);
661 Of_SetSortByArea( pCuts, nCuts );
662 return Abc_MinInt( nCuts + 1, nCutNum - 1 );
663}
664static inline int Of_CutArea( Of_Man_t * p, int nLeaves )
665{
666 if ( nLeaves < 2 )
667 return 0;
668 return nLeaves + p->pPars->nAreaTuner;
669}
670static inline void Of_CutParams( Of_Man_t * p, Of_Cut_t * pCut, int nGiaRefs )
671{
672 int i, nLeaves = pCut->nLeaves;
673 assert( nLeaves <= p->pPars->nLutSize );
674 pCut->Delay = 0;
675 pCut->Flow = 0;
676 for ( i = 0; i < nLeaves; i++ )
677 {
678 pCut->Delay = Abc_MaxInt( pCut->Delay, Of_ObjCutDelay(p, pCut->pLeaves[i]) );
679 pCut->Flow += Of_ObjCutFlow(p, pCut->pLeaves[i]);
680 }
681 pCut->Delay += (int)(nLeaves > 1);
682 pCut->Flow = (pCut->Flow + 100 * Of_CutArea(p, nLeaves)) / (nGiaRefs ? nGiaRefs : 1);
683}
684void Of_ObjMergeOrder( Of_Man_t * p, int iObj )
685{
686 Of_Cut_t pCuts0[OF_CUT_MAX], pCuts1[OF_CUT_MAX], pCuts[OF_CUT_MAX], * pCutsR[OF_CUT_MAX];
687 Gia_Obj_t * pObj = Gia_ManObj(p->pGia, iObj);
688 int nGiaRefs = 2*Gia_ObjRefNumId(p->pGia, iObj);
689 int nLutSize = p->pPars->nLutSize;
690 int nCutNum = p->pPars->nCutNum;
691 int nCuts0 = Of_ManPrepareCuts(pCuts0, p, Gia_ObjFaninId0(pObj, iObj), 1);
692 int nCuts1 = Of_ManPrepareCuts(pCuts1, p, Gia_ObjFaninId1(pObj, iObj), 1);
693 int fComp0 = Gia_ObjFaninC0(pObj);
694 int fComp1 = Gia_ObjFaninC1(pObj);
695 int iSibl = Gia_ObjSibl(p->pGia, iObj);
696 Of_Cut_t * pCut0, * pCut1, * pCut0Lim = pCuts0 + nCuts0, * pCut1Lim = pCuts1 + nCuts1;
697 int i, nCutsR = 0;
698 assert( !Gia_ObjIsBuf(pObj) );
699 for ( i = 0; i < nCutNum; i++ )
700 pCutsR[i] = pCuts + i;
701 if ( iSibl )
702 {
703 Of_Cut_t pCuts2[OF_CUT_MAX];
704 Gia_Obj_t * pObjE = Gia_ObjSiblObj(p->pGia, iObj);
705 int fCompE = Gia_ObjPhase(pObj) ^ Gia_ObjPhase(pObjE);
706 int nCuts2 = Of_ManPrepareCuts(pCuts2, p, iSibl, 0);
707 Of_Cut_t * pCut2, * pCut2Lim = pCuts2 + nCuts2;
708 for ( pCut2 = pCuts2; pCut2 < pCut2Lim; pCut2++ )
709 {
710 *pCutsR[nCutsR] = *pCut2;
711 if ( p->pPars->fCutMin )
712 pCutsR[nCutsR]->iFunc = Abc_LitNotCond( pCutsR[nCutsR]->iFunc, fCompE );
713 Of_CutParams( p, pCutsR[nCutsR], nGiaRefs );
714 nCutsR = Of_SetAddCut( pCutsR, nCutsR, nCutNum );
715 }
716 }
717 if ( Gia_ObjIsMuxId(p->pGia, iObj) )
718 {
719 Of_Cut_t pCuts2[OF_CUT_MAX];
720 int nCuts2 = Of_ManPrepareCuts(pCuts2, p, Gia_ObjFaninId2(p->pGia, iObj), 1);
721 int fComp2 = Gia_ObjFaninC2(p->pGia, pObj);
722 Of_Cut_t * pCut2, * pCut2Lim = pCuts2 + nCuts2;
723 p->CutCount[0] += nCuts0 * nCuts1 * nCuts2;
724 for ( pCut0 = pCuts0; pCut0 < pCut0Lim; pCut0++ )
725 for ( pCut1 = pCuts1; pCut1 < pCut1Lim; pCut1++ )
726 for ( pCut2 = pCuts2; pCut2 < pCut2Lim; pCut2++ )
727 {
728 if ( Of_CutCountBits(pCut0->Sign | pCut1->Sign | pCut2->Sign) > nLutSize )
729 continue;
730 p->CutCount[1]++;
731 if ( !Of_CutMergeOrderMux(pCut0, pCut1, pCut2, pCutsR[nCutsR], nLutSize) )
732 continue;
733 if ( Of_SetLastCutIsContained(pCutsR, nCutsR) )
734 continue;
735 p->CutCount[2]++;
736 if ( p->pPars->fCutMin && Of_CutComputeTruthMux6(p, pCut0, pCut1, pCut2, fComp0, fComp1, fComp2, pCutsR[nCutsR]) )
737 pCutsR[nCutsR]->Sign = Of_CutGetSign(pCutsR[nCutsR]->pLeaves, pCutsR[nCutsR]->nLeaves);
738 Of_CutParams( p, pCutsR[nCutsR], nGiaRefs );
739 nCutsR = Of_SetAddCut( pCutsR, nCutsR, nCutNum );
740 }
741 }
742 else
743 {
744 int fIsXor = Gia_ObjIsXor(pObj);
745 p->CutCount[0] += nCuts0 * nCuts1;
746 for ( pCut0 = pCuts0; pCut0 < pCut0Lim; pCut0++ )
747 for ( pCut1 = pCuts1; pCut1 < pCut1Lim; pCut1++ )
748 {
749 if ( (int)(pCut0->nLeaves + pCut1->nLeaves) > nLutSize && Of_CutCountBits(pCut0->Sign | pCut1->Sign) > nLutSize )
750 continue;
751 p->CutCount[1]++;
752 if ( !Of_CutMergeOrder(pCut0, pCut1, pCutsR[nCutsR], nLutSize) )
753 continue;
754 if ( Of_SetLastCutIsContained(pCutsR, nCutsR) )
755 continue;
756 p->CutCount[2]++;
757 if ( p->pPars->fCutMin && Of_CutComputeTruth6(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) )
758 pCutsR[nCutsR]->Sign = Of_CutGetSign(pCutsR[nCutsR]->pLeaves, pCutsR[nCutsR]->nLeaves);
759 Of_CutParams( p, pCutsR[nCutsR], nGiaRefs );
760 nCutsR = Of_SetAddCut( pCutsR, nCutsR, nCutNum );
761 }
762 }
763 // debug printout
764 if ( 0 )
765 {
766 printf( "*** Obj = %d\n", iObj );
767 for ( i = 0; i < nCutsR; i++ )
768 Of_Cutprintf( p, pCutsR[i] );
769 printf( "\n" );
770 }
771 // verify
772 assert( nCutsR > 0 && nCutsR < nCutNum );
773 //assert( Of_SetCheckArray(pCutsR, nCutsR) );
774 // store the cutset
775 Of_ObjSetCutFlow( p, iObj, pCutsR[0]->Flow );
776 Of_ObjSetCutDelay( p, iObj, pCutsR[0]->Delay );
777 *Vec_IntEntryP(&p->vCutSets, iObj) = Of_ManSaveCuts(p, pCutsR, nCutsR);
778 p->CutCount[3] += nCutsR;
779}
781{
782 Gia_Obj_t * pObj; int i, iFanin;
783 Gia_ManForEachAnd( p->pGia, pObj, i )
784 if ( Gia_ObjIsBuf(pObj) )
785 {
786 iFanin = Gia_ObjFaninId0(pObj, i);
787 Of_ObjSetCutFlow( p, i, Of_ObjCutFlow(p, iFanin) );
788 Of_ObjSetCutDelay( p, i, Of_ObjCutDelay(p, iFanin) );
789 }
790 else
791 Of_ObjMergeOrder( p, i );
792 Gia_ManForEachAnd( p->pGia, pObj, i )
793 if ( !Gia_ObjIsBuf(pObj) )
794 Of_ManLiftCuts( p, i );
795}
796
797
798
799
811void Of_ManPrintStats( Of_Man_t * p, char * pTitle )
812{
813 if ( !p->pPars->fVerbose )
814 return;
815 printf( "%s : ", pTitle );
816 printf( "Delay =%8.2f ", Of_Int2Flt((int)p->pPars->Delay) );
817 printf( "Area =%8d ", (int)p->pPars->Area );
818 printf( "Edge =%9d ", (int)p->pPars->Edge );
819 Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
820 fflush( stdout );
821}
823{
824 int nChoices;
825 if ( !p->pPars->fVerbose )
826 return;
827 printf( "LutSize = %d ", p->pPars->nLutSize );
828 printf( "CutNum = %d ", p->pPars->nCutNum );
829 printf( "Iter = %d ", p->pPars->nRounds + p->pPars->nRoundsEla );
830 printf( "Coarse = %d ", p->pPars->fCoarsen );
831 if ( p->pPars->fCutMin )
832 printf( "Funcs = %d ", Vec_MemEntryNum(p->vTtMem) );
833 nChoices = Gia_ManChoiceNum( p->pGia );
834 if ( nChoices )
835 printf( "Choices = %d ", nChoices );
836 printf( "\n" );
837 printf( "Computing cuts...\r" );
838 fflush( stdout );
839}
841{
842 float MemGia = Gia_ManMemory(p->pGia) / (1<<20);
843 float MemMan = 1.0 * sizeof(Of_Obj_t) * Gia_ManObjNum(p->pGia) / (1<<20);
844 float MemCuts = 1.0 * sizeof(int) * (1 << 16) * Vec_PtrSize(&p->vPages) / (1<<20);
845 float MemTt = p->vTtMem ? Vec_MemMemory(p->vTtMem) / (1<<20) : 0;
846 if ( p->CutCount[0] == 0 )
847 p->CutCount[0] = 1;
848 if ( !p->pPars->fVerbose )
849 return;
850 printf( "CutPair = %.0f ", p->CutCount[0] );
851 printf( "Merge = %.0f (%.1f) ", p->CutCount[1], 1.0*p->CutCount[1]/Gia_ManAndNum(p->pGia) );
852 printf( "Eval = %.0f (%.1f) ", p->CutCount[2], 1.0*p->CutCount[2]/Gia_ManAndNum(p->pGia) );
853 printf( "Cut = %.0f (%.1f) ", p->CutCount[3], 1.0*p->CutCount[3]/Gia_ManAndNum(p->pGia) );
854// printf( "Use = %.0f (%.1f) ", p->CutCount[4], 1.0*p->CutCount[4]/Gia_ManAndNum(p->pGia) );
855// printf( "Mat = %.0f (%.1f) ", p->CutCount[5], 1.0*p->CutCount[5]/Gia_ManAndNum(p->pGia) );
856// printf( "Equ = %d (%.2f %%) ", p->nCutUseAll, 100.0*p->nCutUseAll /p->CutCount[0] );
857 printf( "\n" );
858 printf( "Gia = %.2f MB ", MemGia );
859 printf( "Man = %.2f MB ", MemMan );
860 printf( "Cut = %.2f MB ", MemCuts );
861 if ( p->pPars->fCutMin )
862 printf( "TT = %.2f MB ", MemTt );
863 printf( "Total = %.2f MB ", MemGia + MemMan + MemCuts + MemTt );
864// printf( "\n" );
865 Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
866 fflush( stdout );
867}
868
869
881/*
882static inline int Of_ManComputeForwardCut( Of_Man_t * p, int iObj, int * pCut )
883{
884 int k, iVar, Delay = 0, Area = Of_CutArea(p, Of_CutSize(pCut));
885 int DelayLut1 = p->pPars->nDelayLut1;
886 Of_CutForEachVar( pCut, iVar, k )
887 {
888 Delay = Abc_MaxInt( Delay, Of_ObjDelay1(p, iVar) + DelayLut1 );
889 if ( p->Iter )
890 Area += Of_ObjRefNum(p, iVar) ? 0 : Of_ObjFlow(p, iVar);
891 }
892 Of_CutSetDelay1( pCut, Delay );
893 if ( p->Iter )
894 Of_CutSetAreaFlow( pCut, Area );
895 return Delay;
896}
897static inline void Of_ManComputeForwardObj( Of_Man_t * p, int iObj )
898{
899 int Delay1 = ABC_INFINITY, Area1 = ABC_INFINITY;
900 int * pList = Of_ObjCutSet(p, iObj);
901 int i, * pCut, * pCutMin = NULL, * pCutMin2 = NULL;
902 // compute cut arrivals
903 Of_SetForEachCut( pList, pCut, i )
904 {
905 int Delay1This = Of_ManComputeForwardCut(p, iObj, pCut);
906 if ( Delay1 > Delay1This )
907 {
908 Delay1 = Delay1This;
909 pCutMin = pCut;
910 }
911 if ( p->Iter && Area1 > Of_CutAreaFlow(pCut) )
912 {
913 Area1 = Of_CutAreaFlow(pCut);
914 pCutMin2 = pCut;
915 }
916 }
917 // if mapping is present, set object arrival equal to cut arrival
918 if ( Of_ObjRefNum(p, iObj) )
919 {
920 pCutMin = Of_ObjCutBestP(p, iObj);
921 Delay1 = Of_CutDelay1( pCutMin );
922 Of_ObjSetDelay1( p, iObj, Delay1 );
923 if ( p->Iter )
924 Of_ObjSetFlow( p, iObj, Of_CutAreaFlow(pCutMin) );
925 }
926 else
927 {
928 if ( p->Iter == 0 )
929 {
930 Of_ObjSetCutBestP( p, pList, iObj, pCutMin );
931 Of_ObjSetDelay1( p, iObj, Delay1 );
932 }
933 else
934 {
935 Of_ObjSetCutBestP( p, pList, iObj, pCutMin2 );
936 Of_ObjSetDelay1( p, iObj, Of_CutDelay1(pCutMin2) );
937 Of_ObjSetFlow( p, iObj, Of_CutAreaFlow(pCutMin2) );
938 }
939 }
940}
941*/
942
943/*
944int * Of_CutReferChooseCut( Of_Man_t * p, int Var, int Required, int fSetBest )
945{
946 int i, CostMin = ABC_INFINITY;
947 int * pCutMin = NULL, * pList = Of_ObjCutSet(p, Var);
948 int * pCut = Of_ObjCutBestP(p, Var);
949 assert( Of_CutDelay1(pCut) <= Required );
950// return pCut;
951 // choose cut with smaller area
952 Of_SetForEachCut( pList, pCut, i )
953 {
954 if ( Of_CutDelay1(pCut) > Required )
955 continue;
956 if ( CostMin > Of_CutAreaFlow(pCut) )
957 {
958 CostMin = Of_CutAreaFlow(pCut);
959 pCutMin = pCut;
960 }
961 }
962 assert( pCutMin != NULL );
963 assert( Of_CutDelay1(pCutMin) <= Required );
964 if ( fSetBest )
965 Of_ObjSetCutBestP( p, pList, Var, pCutMin );
966 return pCutMin;
967}
968int Of_CutRef2_rec( Of_Man_t * p, int * pCut, int Required, int fSetBest )
969{
970 int i, Var, Count = Of_CutArea(p, Of_CutSize(pCut));
971 assert( Of_CutDelay1(pCut) <= Required );
972 Required -= p->pPars->nDelayLut1;
973 Of_CutForEachVar( pCut, Var, i )
974 {
975 if ( !Of_ObjCutBest(p, Var) )
976 continue;
977 if ( !fSetBest )
978 Vec_IntPush( &p->vCutRefs, Var );
979 if ( Of_ObjRefInc(p, Var) )
980 continue;
981 Count += Of_CutRef2_rec( p, Of_CutReferChooseCut(p, Var, Required, fSetBest), Required, fSetBest );
982 }
983 return Count;
984}
985static inline int Of_CutAreaDerefed2( Of_Man_t * p, int * pCut, int Required )
986{
987 int Ela1, i, iObj;
988 assert( Vec_IntSize(&p->vCutRefs) == 0 );
989 Ela1 = Of_CutRef2_rec( p, pCut, Required, 0 );
990 Vec_IntForEachEntry( &p->vCutRefs, iObj, i )
991 Of_ObjRefDec(p, iObj);
992 Vec_IntClear( &p->vCutRefs );
993 return Ela1;
994}
995*/
996
997
998static inline int Of_ManComputeForwardCut( Of_Man_t * p, int iObj, int * pCut )
999{
1000 int k, iVar, Delay = 0;
1001 int DelayLut1 = p->pPars->nDelayLut1;
1002 Of_CutForEachVar( pCut, iVar, k )
1003 Delay = Abc_MaxInt( Delay, Of_ObjDelay1(p, iVar) + DelayLut1 );
1004 Of_CutSetDelay1( pCut, Delay );
1005 return Delay;
1006}
1007static inline int Of_ManComputeForwardCutArea( Of_Man_t * p, int iObj, int * pCut )
1008{
1009 int k, iVar, Area = 100 * Of_CutArea(p, Of_CutSize(pCut));
1010 Of_CutForEachVar( pCut, iVar, k )
1011 Area += Of_ObjFlow(p, iVar);
1012 return Area / Abc_MaxInt(1, Of_ObjRefNum(p, iObj));
1013}
1014static inline void Of_ManComputeForwardObj( Of_Man_t * p, int iObj )
1015{
1016 int Delay1 = ABC_INFINITY;
1017 int i, * pCut, * pCutMin = NULL, * pList = Of_ObjCutSet(p, iObj);
1018 // compute cut arrivals
1019 Of_SetForEachCut( pList, pCut, i )
1020 {
1021 int Delay1This = Of_ManComputeForwardCut(p, iObj, pCut);
1022 if ( Delay1 > Delay1This )
1023 {
1024 Delay1 = Delay1This;
1025 pCutMin = pCut;
1026 }
1027 }
1028 // if mapping is present, set object arrival equal to cut arrival
1029 if ( Of_ObjRefNum(p, iObj) )
1030 pCutMin = Of_ObjCutBestP(p, iObj);
1031 Of_ObjSetCutBestP( p, pList, iObj, pCutMin );
1032 Of_ObjSetDelay1( p, iObj, Of_CutDelay1(pCutMin) );
1033 if ( p->Iter )
1034 Of_ObjSetFlow( p, iObj, Of_ManComputeForwardCutArea(p, iObj, pCutMin) );
1035}
1037{
1038 Gia_Obj_t * pObj; int i;
1039 Gia_ManForEachAnd( p->pGia, pObj, i )
1040 if ( Gia_ObjIsBuf(pObj) )
1041 Of_ObjSetDelay1( p, i, Of_ObjDelay1(p, Gia_ObjFaninId0(pObj, i)) );
1042 else
1043 Of_ManComputeForwardObj( p, i );
1044}
1045
1046
1047int Of_CutRef_rec( Of_Man_t * p, int * pCut )
1048{
1049 int i, Var, Count = (p->Iter & 1) ? 1 : Of_CutArea(p, Of_CutSize(pCut));
1050 Of_CutForEachVar( pCut, Var, i )
1051 if ( Of_ObjCutBest(p, Var) && !Of_ObjRefInc(p, Var) )
1052 Count += Of_CutRef_rec( p, Of_ObjCutBestP(p, Var) );
1053 return Count;
1054}
1055int Of_CutDeref_rec( Of_Man_t * p, int * pCut )
1056{
1057 int i, Var, Count = (p->Iter & 1) ? 1 : Of_CutArea(p, Of_CutSize(pCut));
1058 Of_CutForEachVar( pCut, Var, i )
1059 if ( Of_ObjCutBest(p, Var) && !Of_ObjRefDec(p, Var) )
1060 Count += Of_CutDeref_rec( p, Of_ObjCutBestP(p, Var) );
1061 return Count;
1062}
1063static inline int Of_CutAreaDerefed( Of_Man_t * p, int * pCut )
1064{
1065 int Ela1 = Of_CutRef_rec( p, pCut );
1066 int Ela2 = Of_CutDeref_rec( p, pCut );
1067 assert( Ela1 == Ela2 );
1068 return Ela1;
1069}
1070
1071int Of_CutRef2_rec( Of_Man_t * p, int * pCut )
1072{
1073 int i, Var, Count = (p->Iter & 1) ? 1 : Of_CutArea(p, Of_CutSize(pCut));
1074 Of_CutForEachVar( pCut, Var, i )
1075 {
1076 if ( !Of_ObjCutBest(p, Var) )
1077 continue;
1078 Vec_IntPush( &p->vCutRefs, Var );
1079 if ( Of_ObjRefInc(p, Var) )
1080 continue;
1081 Count += Of_CutRef2_rec( p, Of_ObjCutBestP(p, Var) );
1082 }
1083 return Count;
1084}
1085static inline int Of_CutAreaDerefed2( Of_Man_t * p, int * pCut )
1086{
1087 int Ela1, i, iObj;
1088 assert( Vec_IntSize(&p->vCutRefs) == 0 );
1089 Ela1 = Of_CutRef2_rec( p, pCut );
1090 Vec_IntForEachEntry( &p->vCutRefs, iObj, i )
1091 Of_ObjRefDec(p, iObj);
1092 Vec_IntClear( &p->vCutRefs );
1093 return Ela1;
1094}
1095
1096
1097static inline void Of_ManComputeForwardObj2( Of_Man_t * p, int iObj )
1098{
1099 int Delay, Required = Of_ObjRequired(p, iObj);
1100 int AreaBef = 0, AreaAft = 0, Area, AreaMin = ABC_INFINITY;
1101 int k, * pCut, * pCutMin = NULL, * pList = Of_ObjCutSet(p, iObj);
1102 if ( Of_ObjRefNum(p, iObj) )
1103 AreaBef = Of_CutDeref_rec( p, Of_ObjCutBestP(p, iObj) );
1104 Of_SetForEachCut( pList, pCut, k )
1105 {
1106 Delay = Of_ManComputeForwardCut(p, iObj, pCut);
1107 if ( Delay > Required )
1108 continue;
1109 Area = Of_CutAreaDerefed2( p, pCut );
1110 if ( AreaMin > Area )
1111 {
1112 AreaMin = Area;
1113 pCutMin = pCut;
1114 }
1115 }
1116 assert( pCutMin != NULL );
1117 Of_ObjSetCutBestP( p, pList, iObj, pCutMin );
1118 if ( Of_ObjRefNum(p, iObj) )
1119 AreaAft = Of_CutRef_rec( p, pCutMin );
1120 assert( AreaAft <= AreaBef );
1121 Delay = Of_CutDelay1(pCutMin);
1122 assert( Delay <= Required );
1123 Of_ObjSetDelay1( p, iObj, Delay );
1124}
1126{
1127 Gia_Obj_t * pObj; int i;
1128 Gia_ManForEachAnd( p->pGia, pObj, i )
1129 if ( Gia_ObjIsBuf(pObj) )
1130 Of_ObjSetDelay1( p, i, Of_ObjDelay1(p, Gia_ObjFaninId0(pObj, i)) );
1131 else
1132 Of_ManComputeForwardObj2( p, i );
1133}
1134
1135
1136static inline int Of_ManComputeOutputRequired( Of_Man_t * p, int fCleanRefs )
1137{
1138 int i, Id, Delay = 0;
1139 for ( i = 0; i < Gia_ManObjNum(p->pGia); i++ )
1140 {
1141 Of_ObjSetRequired( p, i, ABC_INFINITY );
1142 if ( fCleanRefs )
1143 Of_ObjSetRefNum( p, i, 0 );
1144 }
1145 Gia_ManForEachCoDriverId( p->pGia, Id, i )
1146 Delay = Abc_MaxInt( Delay, Of_ObjDelay1(p, Id) );
1147 Gia_ManForEachCoDriverId( p->pGia, Id, i )
1148 {
1149 Of_ObjUpdateRequired( p, Id, Delay );
1150 if ( fCleanRefs )
1151 Of_ObjRefInc( p, Id );
1152 }
1153 if ( p->pPars->Delay && p->pPars->Delay < Delay )
1154 printf( "Error: Delay violation.\n" );
1155 p->pPars->Delay = Delay;
1156 return Delay;
1157}
1158static inline int Of_ManComputeBackwardCut( Of_Man_t * p, int * pCut )
1159{
1160 int k, iVar, Cost = 0;
1161 Of_CutForEachVar( pCut, iVar, k )
1162 if ( !Of_ObjRefNum(p, iVar) )
1163 Cost += Of_ObjFlow( p, iVar );
1164 return Cost;
1165}
1167{
1168 Gia_Obj_t * pObj;
1169 int DelayLut1 = p->pPars->nDelayLut1;
1170 int i, k, iVar, * pList, * pCut, * pCutMin;
1171 Of_ManComputeOutputRequired( p, 1 );
1172 // compute area and edges
1173 p->pPars->Area = p->pPars->Edge = 0;
1174 Gia_ManForEachAndReverse( p->pGia, pObj, i )
1175 {
1176 int CostMin, Cost, Required = Of_ObjRequired(p, i);
1177 if ( Gia_ObjIsBuf(pObj) )
1178 {
1179 int FaninId = Gia_ObjFaninId0(pObj, i);
1180 Of_ObjUpdateRequired( p, FaninId, Required );
1181 Of_ObjRefInc( p, FaninId );
1182 continue;
1183 }
1184 if ( !Of_ObjRefNum(p, i) )
1185 continue;
1186 // select the best cut
1187 pCutMin = NULL;
1188 CostMin = ABC_INFINITY;
1189 pList = Of_ObjCutSet( p, i );
1190 Of_SetForEachCut( pList, pCut, k )
1191 {
1192 if ( Of_CutDelay1(pCut) > Required )
1193 continue;
1194 Cost = Of_ManComputeBackwardCut( p, pCut );
1195 if ( CostMin > Cost )
1196 {
1197 CostMin = Cost;
1198 pCutMin = pCut;
1199 }
1200 }
1201 // the cut is selected
1202 assert( pCutMin != NULL );
1203 Of_ObjSetCutBestP( p, pList, i, pCutMin );
1204 Of_CutForEachVar( pCutMin, iVar, k )
1205 {
1206 Of_ObjUpdateRequired( p, iVar, Required - DelayLut1 );
1207 Of_ObjRefInc( p, iVar );
1208 }
1209 // update parameters
1210 p->pPars->Edge += Of_CutSize(pCutMin);
1211 p->pPars->Area++;
1212 }
1213}
1215{
1216 Gia_Obj_t * pObj;
1217 int DelayLut1 = p->pPars->nDelayLut1;
1218 int i, k, iVar, * pCutMin;
1219 Of_ManComputeOutputRequired( p, 0 );
1220 // compute area and edges
1221 p->pPars->Area = p->pPars->Edge = 0;
1222 Gia_ManForEachAndReverse( p->pGia, pObj, i )
1223 {
1224 int Required = Of_ObjRequired(p, i);
1225 if ( Gia_ObjIsBuf(pObj) )
1226 {
1227 int FaninId = Gia_ObjFaninId0(pObj, i);
1228 Of_ObjUpdateRequired( p, FaninId, Required );
1229 continue;
1230 }
1231 if ( !Of_ObjRefNum(p, i) )
1232 continue;
1233 // lookup for the cut
1234 pCutMin = Of_ObjCutBestP( p, i );
1235 Of_CutForEachVar( pCutMin, iVar, k )
1236 Of_ObjUpdateRequired( p, iVar, Required - DelayLut1 );
1237 // update parameters
1238 p->pPars->Edge += Of_CutSize(pCutMin);
1239 p->pPars->Area++;
1240 }
1241}
1243{
1244 Gia_Obj_t * pObj;
1245 int DelayLut1 = p->pPars->nDelayLut1;
1246 int i, k, iVar, * pList, * pCut, * pCutMin;
1247 int AreaBef = 0, AreaAft = 0;
1248 Of_ManComputeOutputRequired( p, 0 );
1249 // compute area and edges
1250 p->pPars->Area = p->pPars->Edge = 0;
1251 Gia_ManForEachAndReverse( p->pGia, pObj, i )
1252 {
1253 int CostMin, Cost, Required = Of_ObjRequired(p, i);
1254 if ( Gia_ObjIsBuf(pObj) )
1255 {
1256 int FaninId = Gia_ObjFaninId0(pObj, i);
1257 Of_ObjUpdateRequired( p, FaninId, Required );
1258 continue;
1259 }
1260 if ( !Of_ObjRefNum(p, i) )
1261 continue;
1262 // deref best cut
1263 AreaBef = Of_CutDeref_rec( p, Of_ObjCutBestP(p, i) );
1264 // select the best cut
1265 pCutMin = NULL;
1266 CostMin = ABC_INFINITY;
1267 pList = Of_ObjCutSet( p, i );
1268 Of_SetForEachCut( pList, pCut, k )
1269 {
1270 if ( Of_CutDelay1(pCut) > Required )
1271 continue;
1272 Cost = Of_CutAreaDerefed2( p, pCut );
1273 if ( CostMin > Cost )
1274 {
1275 CostMin = Cost;
1276 pCutMin = pCut;
1277 }
1278 }
1279 // the cut is selected
1280 assert( pCutMin != NULL );
1281 Of_ObjSetCutBestP( p, pList, i, pCutMin );
1282 Of_CutForEachVar( pCutMin, iVar, k )
1283 Of_ObjUpdateRequired( p, iVar, Required - DelayLut1 );
1284 // ref best cut
1285 AreaAft = Of_CutRef_rec( p, pCutMin );
1286 assert( AreaAft <= AreaBef );
1287 // update parameters
1288 p->pPars->Edge += Of_CutSize(pCutMin);
1289 p->pPars->Area++;
1290 }
1291}
1292
1304void Of_ManComputeForwardDirconCut( Of_Man_t * p, int iObj, int * pCut, int * pDelay1, int * pDelay2 )
1305{
1306 // Delay1 - main delay; Delay2 - precomputed LUT delay in terms of Delay1 for the fanins
1307 int Delays[6], Perm[6] = {0, 1, 2, 3, 4, 5};
1308 int DelayLut1 = p->pPars->nDelayLut1;
1309 int DelayLut2 = p->pPars->nDelayLut2;
1310 int nSize = Of_CutSize(pCut);
1311 int k, iVar, Flag, SlowCon, Delay, DelayAfter, fDirConWorks;
1312 Of_CutForEachVar( pCut, iVar, k )
1313 {
1314 Delays[k] = Of_ObjDelay1(p, iVar) + DelayLut1;
1315// printf( "%3d%s ", iVar, Flag ? "*" : " " );
1316 }
1317 for ( ; k < p->pPars->nLutSize; k++ )
1318 {
1319 Delays[k] = -ABC_INFINITY;
1320// printf( " " );
1321 }
1322 Vec_IntSelectSortCost2Reverse( Perm, nSize, Delays );
1323 assert( nSize < 2 || Delays[0] >= Delays[nSize-1] );
1324 assert( Delays[0] >= 0 && Delays[nSize-1] >= 0 );
1325 // consider speedup due to dircons
1326 fDirConWorks = 1;
1327 *pDelay1 = *pDelay2 = 0;
1328 SlowCon = p->pPars->nFastEdges < nSize ? Delays[p->pPars->nFastEdges] : 0;
1329 for ( k = 0; k < nSize; k++ )
1330 {
1331 // use dircon if the following is true
1332 // - the input is eligible for dircon (does not exceed the limit)
1333 // - there is an expected gain in delay, compared the largest delay without dircon
1334 // - the dircon delay is indeed lower than the largest delay without dircon
1335 // - all previous dircons worked out well
1336 // - the node is an AND-gate
1337 iVar = Of_CutVar( pCut, Perm[k] );
1338 assert( Delays[k] == Of_ObjDelay1(p, iVar) + DelayLut1 );
1339 DelayAfter = Of_ObjDelay2(p, iVar) + DelayLut2;
1340 if ( k < p->pPars->nFastEdges && Delays[k] > SlowCon && DelayAfter < Delays[k] && fDirConWorks && Gia_ObjIsAndNotBuf(Gia_ManObj(p->pGia, iVar)) )
1341 {
1342 Delay = DelayAfter;
1343 Of_CutSetFlag( pCut, Perm[k], 1 );
1344 }
1345 else
1346 {
1347 Delay = Delays[k];// + DelayLut2;
1348 Of_CutSetFlag( pCut, Perm[k], 0 );
1349 fDirConWorks = 0;
1350 }
1351 *pDelay1 = Abc_MaxInt( *pDelay1, Delay );
1352 *pDelay2 = Abc_MaxInt( *pDelay2, Delays[k] );
1353 }
1354// printf( " %5.2f", Of_Int2Flt(*pDelay1) );
1355// printf( " %5.2f\n", Of_Int2Flt(*pDelay2) );
1356 // do not use the structure if simple LUT is better
1357 if ( *pDelay1 > *pDelay2 )
1358 {
1359 for ( k = 0; k < nSize; k++ )
1360 Of_CutSetFlag( pCut, k, 0 );
1361 *pDelay1 = *pDelay2;
1362 }
1363 assert( *pDelay1 <= *pDelay2 );
1364 Of_CutSetDelay1( pCut, *pDelay1 );
1365 Of_CutSetDelay2( pCut, *pDelay2 );
1366 // verify
1367 Of_CutForEachVarFlag( pCut, iVar, Flag, k )
1368 {
1369 if ( Flag )
1370 assert( Of_ObjDelay2(p, iVar) + DelayLut2 <= *pDelay1 );
1371 else
1372 assert( Of_ObjDelay1(p, iVar) + DelayLut1 <= *pDelay1 );
1373 assert( Of_ObjDelay1(p, iVar) + DelayLut1 <= *pDelay2 );
1374 }
1375}
1377{
1378 int Delay1 = ABC_INFINITY, Delay2 = ABC_INFINITY;
1379 int i, * pCut, * pCutMin = NULL, * pCutMin2 = NULL, * pList = Of_ObjCutSet(p, iObj);
1380 Of_SetForEachCut( pList, pCut, i )
1381 {
1382 int Delay1This, Delay2This;
1383 Of_ManComputeForwardDirconCut( p, iObj, pCut, &Delay1This, &Delay2This );
1384 if ( Delay1 > Delay1This )
1385 pCutMin = pCut;
1386 if ( Delay2 > Delay2This )
1387 pCutMin2 = pCut;
1388 Delay1 = Abc_MinInt( Delay1, Delay1This );
1389 Delay2 = Abc_MinInt( Delay2, Delay2This );
1390 }
1391 Of_ObjSetDelay1( p, iObj, Delay1 );
1392 Of_ObjSetDelay2( p, iObj, Delay2 );
1393 Of_ObjSetCutBestP( p, pList, iObj, pCutMin );
1394 Of_ObjSetCutBestP2( p, pList, iObj, pCutMin2 );
1395 return Delay1;
1396}
1398{
1399 Gia_Obj_t * pObj; int i;
1400 Gia_ManForEachAnd( p->pGia, pObj, i )
1401 if ( Gia_ObjIsBuf(pObj) )
1402 {
1403 Of_ObjSetDelay1( p, i, Of_ObjDelay1(p, Gia_ObjFaninId0(pObj, i)) );
1404 Of_ObjSetDelay2( p, i, Of_ObjDelay2(p, Gia_ObjFaninId0(pObj, i)) );
1405 }
1406 else
1408}
1410{
1411 Gia_Obj_t * pObj;
1412 Vec_Bit_t * vPointed;
1413 int DelayLut1 = p->pPars->nDelayLut1;
1414 int DelayLut2 = p->pPars->nDelayLut2;
1415 int i, k, iVar, Flag, * pList, * pCutMin;
1416 int CountNodes = 0, CountEdges = 0;
1417 Of_ManComputeOutputRequired( p, 1 );
1418 printf( "Global delay =%8.2f\n", Of_Int2Flt((int)p->pPars->Delay) );
1419 //return;
1420 // compute area and edges
1421 vPointed = Vec_BitStart( Gia_ManObjNum(p->pGia) );
1422 p->pPars->Area = p->pPars->Edge = 0;
1423 Gia_ManForEachAndReverse( p->pGia, pObj, i )
1424 {
1425 int CostMin, fPointed, Required = Of_ObjRequired(p, i);
1426 if ( Gia_ObjIsBuf(pObj) )
1427 {
1428 int FaninId = Gia_ObjFaninId0(pObj, i);
1429 Of_ObjUpdateRequired( p, FaninId, Required );
1430 Of_ObjRefInc( p, FaninId );
1431 continue;
1432 }
1433 if ( !Of_ObjRefNum(p, i) )
1434 continue;
1435 // check if the LUT is has an outgoing dircon edge
1436 fPointed = Vec_BitEntry(vPointed, i);
1437 CountNodes += fPointed;
1438
1439/*
1440 // select the best cut
1441 {
1442 int * pCut;
1443 pCutMin = NULL;
1444 CostMin = ABC_INFINITY;
1445 pList = Of_ObjCutSet( p, i );
1446 Of_SetForEachCut( pList, pCut, k )
1447 {
1448 int Cost;
1449 if ( (fPointed ? Of_CutDelay2(pCut) : Of_CutDelay1(pCut)) > Required )
1450 continue;
1451 Cost = Of_ManComputeBackwardCut( p, pCut );
1452 if ( CostMin > Cost )
1453 {
1454 CostMin = Cost;
1455 pCutMin = pCut;
1456 }
1457 }
1458 }
1459*/
1460
1461 if ( fPointed )
1462 {
1463 pCutMin = Of_ObjCutBestP2( p, i );
1464 CostMin = Of_CutDelay2(pCutMin);
1465 //assert( Of_CutDelay2(pCutMin) <= Required );
1466 }
1467 else
1468 {
1469 pCutMin = Of_ObjCutBestP( p, i );
1470 CostMin = Of_CutDelay1(pCutMin);
1471 //assert( Of_CutDelay1(pCutMin) <= Required );
1472 }
1473
1474 // remove dircon markers
1475 //if ( fPointed )
1476 // Of_CutForEachVarFlag( pCutMin, iVar, Flag, k )
1477 // Of_CutSetFlag( pCutMin, k, 0 );
1478
1479 // the cut is selected
1480 assert( pCutMin != NULL );
1481 pList = Of_ObjCutSet( p, i );
1482 Of_ObjSetCutBestP( p, pList, i, pCutMin );
1483 Of_CutForEachVarFlag( pCutMin, iVar, Flag, k )
1484 {
1485 Of_ObjUpdateRequired( p, iVar, Required - ((Flag && !fPointed) ? DelayLut2 : DelayLut1) );
1486 Of_ObjRefInc( p, iVar );
1487 if ( Flag && !fPointed )
1488 {
1489 Vec_BitWriteEntry( vPointed, iVar, 1 );
1490 CountEdges++;
1491 }
1492 }
1493 // update parameters
1494 p->pPars->Edge += Of_CutSize(pCutMin);
1495 p->pPars->Area++;
1496 }
1497 Vec_BitFree( vPointed );
1498 //printf( "Dircon nodes = %d. Dircon edges = %d.\n", CountNodes, CountEdges );
1499}
1500
1512void Of_ManCreateSat( Of_Man_t * p, int nCutsAll, Vec_Int_t * vFirst, Vec_Int_t * vCutNum, Vec_Int_t * vBestNode, Vec_Int_t * vBestCut )
1513{
1514 extern void Cnf_AddCardinConstrPairWise( sat_solver * p, Vec_Int_t * vVars, int K, int fStrict );
1515
1516 Gia_Obj_t * pObj, * pVar;
1517 int * pCutSet, * pCut;
1518 int i, k, v, c, Var, Lit, pLits[2], status, RetValue, nCutCount, nClauses;
1519 Vec_Int_t * vLits = Vec_IntAlloc( 100 );
1520 abctime clk = Abc_Clock();
1521
1522 // start solver
1523 sat_solver * pSat = sat_solver_new();
1524 sat_solver_setnvars( pSat, Gia_ManAndNum(p->pGia) + nCutsAll );
1525
1526 // set polarity
1527 Vec_IntAppend( vBestNode, vBestCut );
1528 //Vec_IntPrint( vBestNode );
1529 sat_solver_set_polarity( pSat, Vec_IntArray(vBestNode), Vec_IntSize(vBestNode) );
1530 Vec_IntShrink( vBestNode, Vec_IntSize(vBestNode) - Vec_IntSize(vBestCut) );
1531
1532 // add clauses for nodes
1533 Gia_ManForEachAnd( p->pGia, pObj, i )
1534 {
1535 int iFirst = Vec_IntEntry(vFirst, i);
1536 int nCuts = Vec_IntEntry(vCutNum, i);
1537 Vec_IntClear( vLits );
1538 Vec_IntPush( vLits, Abc_Var2Lit(pObj->Value, 1) );
1539 for ( c = 0; c < nCuts; c++ )
1540 Vec_IntPush( vLits, Abc_Var2Lit(iFirst + c, 0) );
1541 RetValue = sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntLimit(vLits) );
1542 assert( RetValue );
1543 }
1544
1545 // add clauses for cuts
1546 nCutCount = 0;
1547 Gia_ManForEachAnd( p->pGia, pObj, i )
1548 {
1549 pCutSet = Of_ObjCutSet(p, i);
1550 Of_SetForEachCut( pCutSet, pCut, k )
1551 {
1552 pLits[0] = Abc_Var2Lit( Gia_ManAndNum(p->pGia) + nCutCount, 1 );
1553 pLits[1] = Abc_Var2Lit( pObj->Value, 0 );
1554 RetValue = sat_solver_addclause( pSat, pLits, pLits+2 );
1555 assert( RetValue );
1556 Of_CutForEachVar( pCut, Var, v )
1557 {
1558 pVar = Gia_ManObj(p->pGia, Var);
1559 if ( !Gia_ObjIsAnd(pVar) )
1560 continue;
1561 pLits[1] = Abc_Var2Lit( pVar->Value, 0 );
1562 RetValue = sat_solver_addclause( pSat, pLits, pLits+2 );
1563 assert( RetValue );
1564 }
1565 nCutCount++;
1566 }
1567 }
1568 assert( nCutCount == nCutsAll );
1569
1570 // mark CO drivers
1571 Gia_ManForEachCo( p->pGia, pObj, i )
1572 Gia_ObjFanin0(pObj)->fMark0 = 1;
1573 // set used nodes to 1
1574 Gia_ManForEachAnd( p->pGia, pObj, i )
1575 if ( pObj->fMark0 )
1576 {
1577 Lit = Abc_Var2Lit( pObj->Value, 0 );
1578 RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 );
1579 assert( RetValue );
1580 }
1581 // unmark CO drivers
1582 Gia_ManForEachCo( p->pGia, pObj, i )
1583 Gia_ObjFanin0(pObj)->fMark0 = 0;
1584
1585// Sat_SolverWriteDimacs( pSat, "temp.cnf", NULL, NULL, 0 );
1586
1587 // add cardinality constraint
1588 nClauses = pSat->stats.clauses;
1589 Vec_IntClear( vLits );
1590 Vec_IntFillNatural( vLits, Gia_ManAndNum(p->pGia) );
1591 Cnf_AddCardinConstrPairWise( pSat, vLits, Vec_IntSize(vBestNode)-2, 0 );
1592 printf( "Problem clauses = %d. Cardinality clauses = %d.\n", nClauses, pSat->stats.clauses - nClauses );
1593
1594 // solve the problem
1595 status = sat_solver_solve( pSat, NULL, NULL, 1000000, 0, 0, 0 );
1596 if ( status == l_Undef )
1597 printf( "Undecided. " );
1598 if ( status == l_True )
1599 printf( "Satisfiable. " );
1600 if ( status == l_False )
1601 printf( "Unsatisfiable. " );
1602 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
1603 Sat_SolverPrintStats( stdout, pSat );
1604 if ( status == l_True )
1605 {
1606 int nOnes = 0;
1607 for ( v = 0; v < Gia_ManAndNum(p->pGia); v++ )
1608 {
1609 printf( "%d", sat_solver_var_value(pSat, v) );
1610 nOnes += sat_solver_var_value(pSat, v);
1611 }
1612 printf( " Nodes = %d\n", nOnes );
1613
1614 nOnes = 0;
1615 for ( ; v < Gia_ManAndNum(p->pGia) + nCutsAll; v++ )
1616 {
1617 printf( "%d", sat_solver_var_value(pSat, v) );
1618 nOnes += sat_solver_var_value(pSat, v);
1619 }
1620 printf( " LUTs = %d\n", nOnes );
1621 }
1622
1623 // cleanup
1624 sat_solver_delete( pSat );
1625 Vec_IntFree( vLits );
1626}
1628{
1629 int fVerbose = 0;
1630 Gia_Obj_t * pObj;
1631 int * pCutSet, * pCut, * pCutBest;
1632 int i, k, v, Var, nCuts;
1633 Vec_Int_t * vFirst = Vec_IntStartFull( Gia_ManObjNum(p->pGia) );
1634 Vec_Int_t * vCutNum = Vec_IntStartFull( Gia_ManObjNum(p->pGia) );
1635 Vec_Int_t * vBestNode = Vec_IntAlloc( 100 );
1636 Vec_Int_t * vBestCut = Vec_IntAlloc( 100 );
1637 int nAndsAll = 0, nCutsAll = 0, Shift = Gia_ManAndNum(p->pGia);
1638 Gia_ManFillValue( p->pGia );
1639 Gia_ManForEachAnd( p->pGia, pObj, i )
1640 {
1641 // get the best cut
1642 pCutBest = NULL;
1643 if ( Of_ObjRefNum(p, i) )
1644 {
1645 Vec_IntPush( vBestNode, nAndsAll );
1646 pCutBest = Of_ObjCutBestP( p, i );
1647 }
1648 pObj->Value = nAndsAll++;
1649 // get the cutset
1650 pCutSet = Of_ObjCutSet(p, i);
1651 // count cuts
1652 nCuts = 0;
1653 Of_SetForEachCut( pCutSet, pCut, k )
1654 nCuts++;
1655 // save
1656 Vec_IntWriteEntry( vFirst, i, Shift + nCutsAll );
1657 Vec_IntWriteEntry( vCutNum, i, nCuts );
1658 // print cuts
1659 if ( fVerbose )
1660 printf( "Node %d. Cuts %d.\n", i, nCuts );
1661 Of_SetForEachCut( pCutSet, pCut, k )
1662 {
1663 if ( fVerbose )
1664 {
1665 printf( "{ " );
1666 Of_CutForEachVar( pCut, Var, v )
1667 printf( "%d ", Var );
1668 printf( "} %s\n", pCutBest == pCut ? "best" :"" );
1669 }
1670 if ( pCutBest == pCut )
1671 Vec_IntPush( vBestCut, Shift + nCutsAll );
1672 nCutsAll++;
1673 }
1674 }
1675 assert( nAndsAll == Shift );
1676 printf( "Total: Ands = %d. Luts = %d. Cuts = %d.\n", nAndsAll, Vec_IntSize(vBestNode), nCutsAll );
1677
1678 // create SAT problem
1679 Of_ManCreateSat( p, nCutsAll, vFirst, vCutNum, vBestNode, vBestCut );
1680
1681 Vec_IntFree( vFirst );
1682 Vec_IntFree( vCutNum );
1683 Vec_IntFree( vBestNode );
1684 Vec_IntFree( vBestCut );
1685}
1686
1699{
1700 memset( pPars, 0, sizeof(Jf_Par_t) );
1701 pPars->nLutSize = 4;
1702 pPars->nCutNum = 16;
1703 pPars->nProcNum = 0;
1704 pPars->nRounds = 3;
1705 pPars->nRoundsEla = 4;
1706 pPars->nRelaxRatio = 0;
1707 pPars->nCoarseLimit = 3;
1708 pPars->nAreaTuner = 10;
1709 pPars->DelayTarget = -1;
1710 pPars->nDelayLut1 = 10;
1711 pPars->nDelayLut2 = 2;
1712 pPars->nFastEdges = 0; //
1713 pPars->fAreaOnly = 0;
1714 pPars->fOptEdge = 1;
1715 pPars->fCoarsen = 0;
1716 pPars->fCutMin = 0;
1717 pPars->fGenCnf = 0;
1718 pPars->fPureAig = 0;
1719 pPars->fVerbose = 0;
1720 pPars->fVeryVerbose = 0;
1721 pPars->nLutSizeMax = OF_LEAF_MAX;
1722 pPars->nCutNumMax = OF_CUT_MAX;
1723 pPars->MapDelayTarget = -1;
1724}
1726{
1727 Vec_Int_t * vMapping, * vPacking = NULL;
1728 Vec_Bit_t * vPointed;
1729 int i, k, iVar, * pCut, Place, Flag;
1730 assert( !p->pPars->fCutMin && p->pGia->vMapping == NULL );
1731 vMapping = Vec_IntAlloc( Gia_ManObjNum(p->pGia) + (int)p->pPars->Edge + (int)p->pPars->Area * 2 );
1732 Vec_IntFill( vMapping, Gia_ManObjNum(p->pGia), 0 );
1733 if ( p->pPars->nFastEdges )
1734 {
1735 vPacking = Vec_IntAlloc( 1000 );
1736 Vec_IntPush( vPacking, 0 );
1737 }
1738 vPointed = Vec_BitStart( Gia_ManObjNum(p->pGia) );
1739 Gia_ManForEachAndId( p->pGia, i )
1740 {
1741 if ( !Of_ObjRefNum(p, i) )
1742 continue;
1743 assert( !Gia_ObjIsBuf(Gia_ManObj(p->pGia,i)) );
1744 pCut = Of_ObjCutBestP( p, i );
1745 Vec_IntWriteEntry( vMapping, i, Vec_IntSize(vMapping) );
1746 Vec_IntPush( vMapping, Of_CutSize(pCut) );
1747 Of_CutForEachVar( pCut, iVar, k )
1748 Vec_IntPush( vMapping, iVar );
1749 Vec_IntPush( vMapping, i );
1750 if ( vPacking == NULL || Vec_BitEntry(vPointed, i) )
1751 continue;
1752 Place = Vec_IntSize( vPacking );
1753 Vec_IntPush( vPacking, 0 );
1754 Vec_IntPush( vPacking, i );
1755 Of_CutForEachVarFlag( pCut, iVar, Flag, k )
1756 if ( Flag )
1757 {
1758 Vec_IntPush( vPacking, iVar );
1759 Vec_BitWriteEntry( vPointed, iVar, 1 );
1760 }
1761 Vec_IntAddToEntry( vPacking, Place, Vec_IntSize(vPacking)-Place-1 );
1762 Vec_IntAddToEntry( vPacking, 0, 1 );
1763 }
1764 assert( Vec_IntCap(vMapping) == 16 || Vec_IntSize(vMapping) == Vec_IntCap(vMapping) );
1765 p->pGia->vMapping = vMapping;
1766 p->pGia->vPacking = vPacking;
1767 Vec_BitFree( vPointed );
1768 return p->pGia;
1769}
1771{
1772 Gia_Man_t * pNew = NULL, * pCls;
1773 Of_Man_t * p; int i, Id;
1774 if ( Gia_ManHasChoices(pGia) )
1775 pPars->fCoarsen = 0, pPars->fCutMin = 1;
1776 pCls = pPars->fCoarsen ? Gia_ManDupMuxes(pGia, pPars->nCoarseLimit) : pGia;
1777 p = Of_StoCreate( pCls, pPars );
1778 if ( pPars->fVerbose && pPars->fCoarsen )
1779 {
1780 printf( "Initial " ); Gia_ManPrintMuxStats( pGia ); printf( "\n" );
1781 printf( "Derived " ); Gia_ManPrintMuxStats( pCls ); printf( "\n" );
1782 }
1783 Of_ManPrintInit( p );
1785 Of_ManPrintQuit( p );
1786
1787 Gia_ManForEachCiId( p->pGia, Id, i )
1788 {
1789 int Time = Of_Flt2Int(p->pGia->vInArrs ? Abc_MaxFloat(0.0, Vec_FltEntry(p->pGia->vInArrs, i)) : 0.0);
1790 Of_ObjSetDelay1( p, Id, Time );
1791 Of_ObjSetDelay2( p, Id, Time );
1792 }
1793
1794 if ( p->pPars->nFastEdges )
1795 {
1796 p->pPars->nRounds = 1;
1797 for ( p->Iter = 0; p->Iter < p->pPars->nRounds; p->Iter++ )
1798 {
1799 if ( p->Iter == 0 )
1800 {
1803 Of_ManPrintStats( p, "Delay" );
1804 }
1805 else
1806 {
1809 Of_ManPrintStats( p, "Flow " );
1810 }
1811 }
1812 }
1813 else
1814 {
1815 for ( p->Iter = 0; p->Iter < p->pPars->nRounds; p->Iter++ )
1816 {
1817 if ( p->Iter == 0 )
1818 {
1821 Of_ManPrintStats( p, "Delay" );
1822 }
1823 else
1824 {
1827 Of_ManPrintStats( p, "Flow " );
1828 }
1829 }
1830 for ( ; p->Iter < p->pPars->nRounds + p->pPars->nRoundsEla; p->Iter++ )
1831 {
1832 if ( p->Iter < p->pPars->nRounds + p->pPars->nRoundsEla - 1 )
1833 {
1836 Of_ManPrintStats( p, "Area " );
1837 }
1838 else
1839 {
1842 Of_ManPrintStats( p, "Area " );
1843 }
1844 }
1845 }
1846
1847 pNew = Of_ManDeriveMapping( p );
1848 Gia_ManMappingVerify( pNew );
1849 if ( pNew->vPacking )
1851 //Of_ManPrintCuts( p );
1852 Of_StoDelete( p );
1853 if ( pCls != pGia )
1854 Gia_ManStop( pCls );
1855 if ( pNew == NULL )
1856 return Gia_ManDup( pGia );
1857 return pNew;
1858}
1859
1863
1864
1866
#define ABC_SWAP(Type, a, b)
Definition abc_global.h:253
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_INFINITY
MACRO DEFINITIONS ///.
Definition abc_global.h:250
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#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
#define l_True
Definition bmcBmcS.c:35
#define l_Undef
Definition bmcBmcS.c:34
#define l_False
Definition bmcBmcS.c:36
void Cnf_AddCardinConstrPairWise(sat_solver *p, Vec_Int_t *vVars, int K, int fStrict)
Definition bmcFault.c:168
#define sat_solver_addclause
Definition cecSatG2.c:37
#define sat_solver
Definition cecSatG2.c:34
#define sat_solver_solve
Definition cecSatG2.c:45
void Dau_DsdPrintFromTruth(word *pTruth, int nVarsInit)
Definition dauDsd.c:1968
Cube * p
Definition exorList.c:222
int Var
Definition exorList.c:228
void Mf_ManSetFlowRefs(Gia_Man_t *p, Vec_Int_t *vRefs)
Definition giaMf.c:1137
Gia_Man_t * Of_ManDeriveMapping(Of_Man_t *p)
Definition giaOf.c:1725
void Of_ManComputeForwardDirconCut(Of_Man_t *p, int iObj, int *pCut, int *pDelay1, int *pDelay2)
Definition giaOf.c:1304
int Of_CutRef_rec(Of_Man_t *p, int *pCut)
Definition giaOf.c:1047
void Of_ManComputeCuts(Of_Man_t *p)
Definition giaOf.c:780
void Of_ManPrintCuts(Of_Man_t *p)
Definition giaOf.c:1627
void Of_ManSetDefaultPars(Jf_Par_t *pPars)
Definition giaOf.c:1698
void Of_ManComputeBackward3(Of_Man_t *p)
Definition giaOf.c:1242
void Of_ObjMergeOrder(Of_Man_t *p, int iObj)
Definition giaOf.c:684
void Of_ManPrintStats(Of_Man_t *p, char *pTitle)
Definition giaOf.c:811
int Of_ManComputeForwardDirconObj(Of_Man_t *p, int iObj)
Definition giaOf.c:1376
struct Of_Cut_t_ Of_Cut_t
Definition giaOf.c:44
#define Of_SetForEachCut(pList, pCut, i)
Definition giaOf.c:150
#define OF_NO_FUNC
Definition giaOf.c:41
struct Of_Obj_t_ Of_Obj_t
Definition giaOf.c:54
void Of_ManComputeBackwardDircon1(Of_Man_t *p)
Definition giaOf.c:1409
Gia_Man_t * Of_ManPerformMapping(Gia_Man_t *pGia, Jf_Par_t *pPars)
Definition giaOf.c:1770
void Of_ManPrintInit(Of_Man_t *p)
Definition giaOf.c:822
#define OF_NUMINV
Definition giaOf.c:89
void Of_ManPrintQuit(Of_Man_t *p)
Definition giaOf.c:840
#define OF_NUM
Definition giaOf.c:88
void Of_ManAreaFlow(Of_Man_t *p)
FUNCTION DEFINITIONS ///.
Definition giaOf.c:170
Of_Man_t * Of_StoCreate(Gia_Man_t *pGia, Jf_Par_t *pPars)
Definition giaOf.c:205
int Of_CutDeref_rec(Of_Man_t *p, int *pCut)
Definition giaOf.c:1055
void Of_ManComputeBackward2(Of_Man_t *p)
Definition giaOf.c:1214
#define OF_CUT_EXTRA
Definition giaOf.c:42
void Of_ManComputeForward1(Of_Man_t *p)
Definition giaOf.c:1036
void Of_ManComputeForward2(Of_Man_t *p)
Definition giaOf.c:1125
void Of_ManCreateSat(Of_Man_t *p, int nCutsAll, Vec_Int_t *vFirst, Vec_Int_t *vCutNum, Vec_Int_t *vBestNode, Vec_Int_t *vBestCut)
Definition giaOf.c:1512
#define OF_CUT_MAX
Definition giaOf.c:39
int Of_CutRef2_rec(Of_Man_t *p, int *pCut)
Definition giaOf.c:1071
void Of_StoDelete(Of_Man_t *p)
Definition giaOf.c:244
#define Of_CutForEachVar(pCut, iVar, i)
Definition giaOf.c:152
void Of_ManComputeBackward1(Of_Man_t *p)
Definition giaOf.c:1166
#define OF_NO_LEAF
Definition giaOf.c:40
void Of_ManComputeForwardDircon1(Of_Man_t *p)
Definition giaOf.c:1397
#define OF_LEAF_MAX
DECLARATIONS ///.
Definition giaOf.c:38
#define Of_CutForEachVarFlag(pCut, iVar, Flag, i)
Definition giaOf.c:153
struct Of_Man_t_ Of_Man_t
Definition giaOf.c:66
void Gia_ManStop(Gia_Man_t *p)
Definition giaMan.c:82
Gia_Man_t * Gia_ManDup(Gia_Man_t *p)
Definition giaDup.c:720
Gia_Man_t * Gia_ManDupMuxes(Gia_Man_t *p, int Limit)
Definition giaMuxes.c:98
double Gia_ManMemory(Gia_Man_t *p)
Definition giaMan.c:194
void Gia_ManConvertPackingToEdges(Gia_Man_t *p)
Definition giaEdge.c:118
#define Gia_ManForEachAnd(p, pObj, i)
Definition gia.h:1214
#define Gia_ManForEachAndReverse(p, pObj, i)
Definition gia.h:1222
#define Gia_ManForEachCoDriverId(p, DriverId, i)
Definition gia.h:1246
struct Gia_Obj_t_ Gia_Obj_t
Definition gia.h:76
void Gia_ManFillValue(Gia_Man_t *p)
Definition giaUtil.c:369
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
void Gia_ManPrintMuxStats(Gia_Man_t *p)
Definition giaMuxes.c:63
void Gia_ManMappingVerify(Gia_Man_t *p)
Definition giaIf.c:2257
void Gia_ManCreateRefs(Gia_Man_t *p)
Definition giaUtil.c:779
struct Jf_Par_t_ Jf_Par_t
Definition gia.h:333
#define Gia_ManForEachCo(p, pObj, i)
Definition gia.h:1236
void Gia_ManSetPhase(Gia_Man_t *p)
Definition giaUtil.c:420
#define Gia_ManForEachAndId(p, i)
Definition gia.h:1216
#define Gia_ManForEachCiId(p, Id, i)
Definition gia.h:1230
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
sat_solver * sat_solver_new(void)
Definition satSolver.c:1137
void sat_solver_setnvars(sat_solver *s, int n)
Definition satSolver.c:1272
void sat_solver_delete(sat_solver *s)
Definition satSolver.c:1341
void Sat_SolverPrintStats(FILE *pFile, sat_solver *p)
Definition satUtil.c:193
Vec_Int_t * vCellMapping
Definition gia.h:139
Vec_Int_t * vPacking
Definition gia.h:141
int * pRefs
Definition gia.h:118
unsigned Value
Definition gia.h:89
unsigned fMark0
Definition gia.h:81
float MapDelayTarget
Definition gia.h:387
int nDelayLut2
Definition gia.h:347
int nDelayLut1
Definition gia.h:346
int nRounds
Definition gia.h:339
int fGenCnf
Definition gia.h:360
int nFastEdges
Definition gia.h:348
int nProcNum
Definition gia.h:338
int nRelaxRatio
Definition gia.h:341
int nCutNum
Definition gia.h:337
int nRoundsEla
Definition gia.h:340
int fOptEdge
Definition gia.h:354
int fAreaOnly
Definition gia.h:350
int nCutNumMax
Definition gia.h:373
int fCoarsen
Definition gia.h:357
int nLutSizeMax
Definition gia.h:372
int nLutSize
Definition gia.h:336
int nAreaTuner
Definition gia.h:343
int fVeryVerbose
Definition gia.h:371
int fCutMin
Definition gia.h:358
int fPureAig
Definition gia.h:365
int nCoarseLimit
Definition gia.h:342
int fVerbose
Definition gia.h:370
int DelayTarget
Definition gia.h:349
int pLeaves[OF_LEAF_MAX+1]
Definition giaOf.c:52
unsigned iFunc
Definition giaOf.c:50
int Delay
Definition giaOf.c:48
word Sign
Definition giaOf.c:47
unsigned nLeaves
Definition giaOf.c:51
int Flow
Definition giaOf.c:49
Vec_Mem_t * vTtMem
Definition giaOf.c:73
double CutCount[6]
Definition giaOf.c:85
Jf_Par_t * pPars
Definition giaOf.c:71
int iCur
Definition giaOf.c:79
Of_Obj_t * pObjs
Definition giaOf.c:82
Vec_Int_t vCutDelays
Definition giaOf.c:77
Vec_Int_t vCutFlows
Definition giaOf.c:76
Vec_Int_t vCutRefs
Definition giaOf.c:78
Vec_Int_t vCutSets
Definition giaOf.c:75
Vec_Ptr_t vPages
Definition giaOf.c:74
abctime clkStart
Definition giaOf.c:84
Gia_Man_t * pGia
Definition giaOf.c:70
int Iter
Definition giaOf.c:80
int iCutH
Definition giaOf.c:57
int Required
Definition giaOf.c:61
int nRefs
Definition giaOf.c:62
int Delay1
Definition giaOf.c:59
int Temp
Definition giaOf.c:64
int Delay2
Definition giaOf.c:60
int Flow
Definition giaOf.c:63
int iCutH2
Definition giaOf.c:58
stats_t stats
Definition satSolver.h:163
unsigned clauses
Definition satVec.h:155
typedefABC_NAMESPACE_IMPL_START struct Vec_Mem_t_ Vec_Mem_t
DECLARATIONS ///.
Definition utilMem.c:35
#define assert(ex)
Definition util_old.h:213
char * memcpy()
char * memset()
typedefABC_NAMESPACE_HEADER_START struct Vec_Bit_t_ Vec_Bit_t
INCLUDES ///.
Definition vecBit.h:42
#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