ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
giaStr.c
Go to the documentation of this file.
1
20
21#include "gia.h"
22#include "misc/util/utilNam.h"
23#include "misc/vec/vecWec.h"
24#include "misc/tim/tim.h"
25
27
31
32#define STR_SUPER 100
33#define MAX_TREE 10000
34
35enum {
38 STR_PI = 2,
43 STR_PO = 7,
45};
46
47typedef struct Str_Obj_t_ Str_Obj_t;
49{
50 unsigned Type : 4; // object type
51 unsigned nFanins : 28; // fanin count
52 int iOffset; // place where fanins are stored
53 int iTop; // top level MUX
54 int iCopy; // copy of this node
55};
56typedef struct Str_Ntk_t_ Str_Ntk_t;
58{
59 int nObjs; // object count
60 int nObjsAlloc; // alloc objects
61 Str_Obj_t * pObjs; // objects
62 Vec_Int_t vFanins; // object fanins
64 int nTrees;
67};
68typedef struct Str_Man_t_ Str_Man_t;
70{
71 // user data
72 Gia_Man_t * pOld; // manager
73 int nLutSize; // LUT size
74 int fCutMin; // cut minimization
75 // internal data
76 Str_Ntk_t * pNtk; // balanced network
77 // AIG under construction
78 Gia_Man_t * pNew; // newly constructed
79 Vec_Int_t * vDelays; // delays of each object
80};
81
82static inline Str_Obj_t * Str_NtkObj( Str_Ntk_t * p, int i ) { assert( i < p->nObjs ); return p->pObjs + i; }
83static inline int Str_ObjFaninId( Str_Ntk_t * p, Str_Obj_t * pObj, int i ) { return Abc_Lit2Var( Vec_IntEntry(&p->vFanins, pObj->iOffset + i) ); }
84static inline Str_Obj_t * Str_ObjFanin( Str_Ntk_t * p, Str_Obj_t * pObj, int i ) { return Str_NtkObj( p, Str_ObjFaninId(p, pObj, i) ); }
85static inline int Str_ObjFaninC( Str_Ntk_t * p, Str_Obj_t * pObj, int i ) { return Abc_LitIsCompl( Vec_IntEntry(&p->vFanins, pObj->iOffset + i) ); }
86static inline int Str_ObjFaninCopy( Str_Ntk_t * p, Str_Obj_t * pObj, int i ) { return Abc_LitNotCond( Str_ObjFanin(p, pObj, i)->iCopy, Str_ObjFaninC(p, pObj, i) ); }
87static inline int Str_ObjId( Str_Ntk_t * p, Str_Obj_t * pObj ) { return pObj - p->pObjs; }
88
89#define Str_NtkManForEachObj( p, pObj ) \
90 for ( pObj = p->pObjs; Str_ObjId(p, pObj) < p->nObjs; pObj++ )
91#define Str_NtkManForEachObjVec( vVec, p, pObj, i ) \
92 for ( i = 0; (i < Vec_IntSize(vVec)) && ((pObj) = Str_NtkObj(p, Vec_IntEntry(vVec,i))); i++ )
93
97
109static inline int Str_ObjCreate( Str_Ntk_t * p, int Type, int nFanins, int * pFanins )
110{
111 Str_Obj_t * pObj = p->pObjs + p->nObjs; int i;
112 assert( p->nObjs < p->nObjsAlloc );
113 pObj->Type = Type;
114 pObj->nFanins = nFanins;
115 pObj->iOffset = Vec_IntSize(&p->vFanins);
116 pObj->iTop = pObj->iCopy = -1;
117 for ( i = 0; i < nFanins; i++ )
118 {
119 Vec_IntPush( &p->vFanins, pFanins[i] );
120 assert( pFanins[i] >= 0 );
121 }
122 p->nObjCount[Type]++;
123 return Abc_Var2Lit( p->nObjs++, 0 );
124}
125static inline Str_Ntk_t * Str_NtkCreate( int nObjsAlloc, int nFaninsAlloc )
126{
127 Str_Ntk_t * p;
128 p = ABC_CALLOC( Str_Ntk_t, 1 );
129 p->pObjs = ABC_ALLOC( Str_Obj_t, nObjsAlloc );
130 p->nObjsAlloc = nObjsAlloc;
131 Str_ObjCreate( p, STR_CONST0, 0, NULL );
132 Vec_IntGrow( &p->vFanins, nFaninsAlloc );
133 return p;
134}
135static inline void Str_NtkDelete( Str_Ntk_t * p )
136{
137// printf( "Total delay gain = %d.\n", p->DelayGain );
138 ABC_FREE( p->vFanins.pArray );
139 ABC_FREE( p->pObjs );
140 ABC_FREE( p );
141}
142static inline void Str_NtkPs( Str_Ntk_t * p, abctime clk )
143{
144 printf( "Network contains %d ands, %d xors, %d muxes (%d trees in %d groups). ",
145 p->nObjCount[STR_AND], p->nObjCount[STR_XOR], p->nObjCount[STR_MUX], p->nTrees, p->nGroups );
146 Abc_PrintTime( 1, "Time", clk );
147}
148static inline void Str_ObjReadGroup( Str_Ntk_t * p, Str_Obj_t * pObj, int * pnGroups, int * pnMuxes )
149{
150 Str_Obj_t * pObj1, * pObj2;
151 *pnGroups = *pnMuxes = 0;
152 if ( pObj->iTop == 0 )
153 return;
154 pObj1 = Str_NtkObj( p, pObj->iTop );
155 pObj2 = Str_NtkObj( p, pObj1->iTop );
156 *pnMuxes = pObj1 - pObj + 1;
157 *pnGroups = (pObj2 - pObj + 1) / *pnMuxes;
158}
159static inline void Str_NtkPrintGroups( Str_Ntk_t * p )
160{
161 Str_Obj_t * pObj;
162 int nGroups, nMuxes;
163 Str_NtkManForEachObj( p, pObj )
164 if ( pObj->Type == STR_MUX && pObj->iTop > 0 )
165 {
166 Str_ObjReadGroup( p, pObj, &nGroups, &nMuxes );
167 pObj += nGroups * nMuxes - 1;
168 printf( "%d x %d ", nGroups, nMuxes );
169 }
170 printf( "\n" );
171}
173{
174 Gia_Man_t * pNew, * pTemp;
175 Str_Obj_t * pObj; int k;
176 assert( pGia->pMuxes == NULL );
177 pNew = Gia_ManStart( 3 * Gia_ManObjNum(pGia) / 2 );
178 pNew->pName = Abc_UtilStrsav( pGia->pName );
179 pNew->pSpec = Abc_UtilStrsav( pGia->pSpec );
180 Gia_ManHashStart( pNew );
181 Str_NtkManForEachObj( p, pObj )
182 {
183 if ( pObj->Type == STR_PI )
184 pObj->iCopy = Gia_ManAppendCi( pNew );
185 else if ( pObj->Type == STR_AND )
186 {
187 pObj->iCopy = 1;
188 for ( k = 0; k < (int)pObj->nFanins; k++ )
189 pObj->iCopy = Gia_ManHashAnd( pNew, pObj->iCopy, Str_ObjFaninCopy(p, pObj, k) );
190 }
191 else if ( pObj->Type == STR_XOR )
192 {
193 pObj->iCopy = 0;
194 for ( k = 0; k < (int)pObj->nFanins; k++ )
195 pObj->iCopy = Gia_ManHashXor( pNew, pObj->iCopy, Str_ObjFaninCopy(p, pObj, k) );
196 }
197 else if ( pObj->Type == STR_MUX )
198 pObj->iCopy = Gia_ManHashMux( pNew, Str_ObjFaninCopy(p, pObj, 2), Str_ObjFaninCopy(p, pObj, 1), Str_ObjFaninCopy(p, pObj, 0) );
199 else if ( pObj->Type == STR_PO )
200 pObj->iCopy = Gia_ManAppendCo( pNew, Str_ObjFaninCopy(p, pObj, 0) );
201 else if ( pObj->Type == STR_CONST0 )
202 pObj->iCopy = 0;
203 else assert( 0 );
204 }
205 Gia_ManHashStop( pNew );
206// assert( Gia_ManObjNum(pNew) <= Gia_ManObjNum(pGia) );
207 Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia) );
208 pNew = Gia_ManCleanup( pTemp = pNew );
209 Gia_ManStop( pTemp );
210 return pNew;
211}
212
213
226{
227 Gia_Man_t * pNew;
228 Gia_Obj_t * pObj, * pFan0, * pFan1, * pFanC;
229 int i, iLit0, iLit1, fCompl;
230 assert( p->pMuxes == NULL );
231 ABC_FREE( p->pRefs );
233 // discount nodes with one fanout pointed to by MUX type
234 Gia_ManForEachAnd( p, pObj, i )
235 {
236 if ( !Gia_ObjIsMuxType(pObj) )
237 continue;
238 Gia_ObjRefDec(p, Gia_ObjFanin0(pObj));
239 Gia_ObjRefDec(p, Gia_ObjFanin1(pObj));
240 }
241 // start the new manager
242 pNew = Gia_ManStart( Gia_ManObjNum(p) );
243 pNew->pName = Abc_UtilStrsav( p->pName );
244 pNew->pSpec = Abc_UtilStrsav( p->pSpec );
245 pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjsAlloc );
247 Gia_ManConst0(p)->Value = 0;
248 Gia_ManForEachCi( p, pObj, i )
249 pObj->Value = Gia_ManAppendCi( pNew );
250 Gia_ManForEachAnd( p, pObj, i )
251 {
252 if ( !Gia_ObjRefNumId(p, i) )
253 continue;
254 if ( !Gia_ObjIsMuxType(pObj) )
255 pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
256 else if ( Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
257 {
258 iLit0 = Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFan0));
259 iLit1 = Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFan1));
260 fCompl = Abc_LitIsCompl(iLit0) ^ Abc_LitIsCompl(iLit1);
261 pObj->Value = fCompl ^ Gia_ManAppendXorReal( pNew, Abc_LitRegular(iLit0), Abc_LitRegular(iLit1) );
262 }
263 else
264 {
265 pFanC = Gia_ObjRecognizeMux( pObj, &pFan1, &pFan0 );
266 iLit0 = Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFan0));
267 iLit1 = Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFan1));
268 if ( iLit0 == iLit1 )
269 pObj->Value = iLit0;
270 else if ( Abc_Lit2Var(iLit0) == Abc_Lit2Var(iLit1) )
271 {
272 iLit1 = Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFanC));
273 fCompl = Abc_LitIsCompl(iLit0) ^ Abc_LitIsCompl(iLit1);
274 pObj->Value = fCompl ^ Gia_ManAppendXorReal( pNew, Abc_LitRegular(iLit0), Abc_LitRegular(iLit1) );
275 }
276 else
277 pObj->Value = Gia_ManAppendMuxReal( pNew, Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFanC)), Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFan1)), Gia_ObjLitCopy(p, Gia_ObjToLit(p, pFan0)) );
278 }
279 }
280 Gia_ManForEachCo( p, pObj, i )
281 pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
282 Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
283 assert( !Gia_ManHasDangling(pNew) );
284 return pNew;
285}
286
299{
300 if ( !pObj->fMark0 )
301 {
302 Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
303 return;
304 }
305 Vec_IntPush( vNodes, Gia_ObjFaninId2p(p, pObj) );
306 Str_MuxInputsCollect_rec( p, Gia_ObjFanin0(pObj), vNodes );
307 Str_MuxInputsCollect_rec( p, Gia_ObjFanin1(pObj), vNodes );
308}
310{
311 assert( !pObj->fMark0 );
312 pObj->fMark0 = 1;
313 Vec_IntClear( vNodes );
314 Str_MuxInputsCollect_rec( p, pObj, vNodes );
315 pObj->fMark0 = 0;
316}
318{
319 if ( !pObj->fMark0 )
320 return;
321 Str_MuxStructCollect_rec( p, Gia_ObjFanin0(pObj), vNodes );
322 Str_MuxStructCollect_rec( p, Gia_ObjFanin1(pObj), vNodes );
323 Vec_IntPush( vNodes, Gia_ObjId(p, pObj) );
324}
326{
327 assert( !pObj->fMark0 );
328 pObj->fMark0 = 1;
329 Vec_IntClear( vNodes );
330 Str_MuxStructCollect_rec( p, pObj, vNodes );
331 pObj->fMark0 = 0;
332}
334{
335 if ( !pObj->fMark0 )
336 return;
337 Vec_StrPush( vStr, '[' );
338 Vec_StrPush( vStr, '(' );
339 Vec_StrPrintNum( vStr, Gia_ObjFaninId2p(p, pObj) );
340 Vec_StrPush( vStr, ')' );
341 Str_MuxStructDump_rec( p, Gia_ObjFaninC2(p, pObj) ? Gia_ObjFanin0(pObj) : Gia_ObjFanin1(pObj), vStr );
342 Vec_StrPush( vStr, '|' );
343 Str_MuxStructDump_rec( p, Gia_ObjFaninC2(p, pObj) ? Gia_ObjFanin1(pObj) : Gia_ObjFanin0(pObj), vStr );
344 Vec_StrPush( vStr, ']' );
345}
347{
348 assert( !pObj->fMark0 );
349 pObj->fMark0 = 1;
350 Vec_StrClear( vStr );
351 Str_MuxStructDump_rec( p, pObj, vStr );
352 Vec_StrPush( vStr, '\0' );
353 pObj->fMark0 = 0;
354}
356{
357 int Count = 0;
358 for ( ; *p; p++ )
359 Count += (*p == '[');
360 return Count;
361}
363{
364 int fPrintStructs = 0;
365 Abc_Nam_t * pNames;
366 Vec_Wec_t * vGroups;
367 Vec_Str_t * vStr;
368 Gia_Obj_t * pObj, * pFanin;
369 int i, iStructId, fFound;
370 assert( p->pMuxes != NULL );
371 // mark MUXes whose only fanout is a MUX
372 ABC_FREE( p->pRefs );
375 {
376 pObj = Gia_ManObj(p, i);
377 pFanin = Gia_ObjFanin0(pObj);
378 if ( Gia_ObjIsMux(p, pFanin) && Gia_ObjRefNum(p, pFanin) == 1 )
379 pFanin->fMark0 = 1;
380 pFanin = Gia_ObjFanin1(pObj);
381 if ( Gia_ObjIsMux(p, pFanin) && Gia_ObjRefNum(p, pFanin) == 1 )
382 pFanin->fMark0 = 1;
383 }
384 // traverse for top level MUXes
385 vStr = Vec_StrAlloc( 1000 );
386 pNames = Abc_NamStart( 10000, 50 );
387 vGroups = Vec_WecAlloc( 1000 );
388 Vec_WecPushLevel( vGroups );
390 {
391 // skip internal
392 pObj = Gia_ManObj(p, i);
393 if ( pObj->fMark0 )
394 continue;
395 // skip trees of size one
396 if ( !Gia_ObjFanin0(pObj)->fMark0 && !Gia_ObjFanin1(pObj)->fMark0 )
397 continue;
398 // hash the tree
399 Str_MuxStructDump( p, pObj, vStr );
400 iStructId = Abc_NamStrFindOrAdd( pNames, Vec_StrArray(vStr), &fFound );
401 if ( !fFound ) Vec_WecPushLevel( vGroups );
402 assert( Abc_NamObjNumMax(pNames) == Vec_WecSize(vGroups) );
403 Vec_IntPush( Vec_WecEntry(vGroups, iStructId), i );
404 }
405 if ( fPrintStructs )
406 {
407 char * pTemp;
408 Abc_NamManForEachObj( pNames, pTemp, i )
409 {
410 printf( "%5d : ", i );
411 printf( "Occur = %4d ", Vec_IntSize(Vec_WecEntry(vGroups,i)) );
412 printf( "Size = %4d ", Str_ManMuxCountOne(pTemp) );
413 printf( "%s\n", pTemp );
414 }
415 }
416 Abc_NamStop( pNames );
417 Vec_StrFree( vStr );
418 return vGroups;
419}
420Vec_Int_t * Str_ManCreateRoots( Vec_Wec_t * vGroups, int nObjs )
421{ // map tree MUXes into their classes
422 Vec_Int_t * vRoots;
423 Vec_Int_t * vGroup;
424 int i, k, Entry;
425 vRoots = Vec_IntStartFull( nObjs );
426 Vec_WecForEachLevel( vGroups, vGroup, i )
427 Vec_IntForEachEntry( vGroup, Entry, k )
428 Vec_IntWriteEntry( vRoots, Entry, i );
429 return vRoots;
430}
431
433{
434 Gia_Obj_t * pObj;
435 if ( Gia_ObjIsTravIdCurrentId(p, i) )
436 return;
437 Gia_ObjSetTravIdCurrentId(p, i);
438 pObj = Gia_ManObj(p, i);
439 if ( !Gia_ObjIsAnd(pObj) )
440 return;
441 Str_MuxTraverse_rec(p, Gia_ObjFaninId0(pObj, i) );
442 Str_MuxTraverse_rec(p, Gia_ObjFaninId1(pObj, i) );
443 if ( Gia_ObjIsMux(p, pObj) )
444 Str_MuxTraverse_rec(p, Gia_ObjFaninId2(p, i) );
445}
447{ // check that members of each group are not in the TFI of each other
448 Vec_Int_t * vGroup, * vGroup2;
449 int i, k, n, iObj, iObj2;
450
451// vGroup = Vec_WecEntry(vGroups, 7);
452// Vec_IntForEachEntry( vGroup, iObj, n )
453// Gia_ManPrintCone2( p, Gia_ManObj(p, iObj) ), printf( "\n" );
454
455 Vec_WecForEachLevel( vGroups, vGroup, i )
456 Vec_IntForEachEntry( vGroup, iObj, k )
457 {
458 if ( Vec_IntSize(vGroup) == 1 )
459 continue;
460 // high light the cone
462 Str_MuxTraverse_rec( p, iObj );
463 // check that none of the others are highlighted
464 Vec_IntForEachEntry( vGroup, iObj2, n )
465 if ( iObj != iObj2 && Gia_ObjIsTravIdCurrentId(p, iObj2) )
466 break;
467 if ( n == Vec_IntSize(vGroup) )
468 continue;
469 // split the group into individual trees
470 Vec_IntForEachEntryStart( vGroup, iObj2, n, 1 )
471 {
472 vGroup2 = Vec_WecPushLevel( vGroups );
473 vGroup = Vec_WecEntry( vGroups, i );
474 Vec_IntPush( vGroup2, iObj2 );
475 }
476 Vec_IntShrink( vGroup, 1 );
477
478/*
479 // this does not work because there can be a pair of independent trees
480 // with another tree squeezed in between them, so that there is a combo loop
481
482 // divide this group
483 nNew = 0;
484 vGroup2 = Vec_WecPushLevel( vGroups );
485 vGroup = Vec_WecEntry( vGroups, i );
486 Vec_IntForEachEntry( vGroup, iObj2, n )
487 {
488 if ( iObj != iObj2 && Gia_ObjIsTravIdCurrentId(p, iObj2) )
489 Vec_IntPush( vGroup2, iObj2 );
490 else
491 Vec_IntWriteEntry( vGroup, nNew++, iObj2 );
492 }
493 Vec_IntShrink( vGroup, nNew );
494 i--;
495 break;
496*/
497
498/*
499 // check that none of the others are highlighted
500 Vec_IntForEachEntry( vGroup, iObj, n )
501 if ( n != k && Gia_ObjIsTravIdCurrentId(p, iObj) )
502 {
503 printf( "Overlap of TFI cones of trees %d and %d in group %d of size %d!\n", k, n, i, Vec_IntSize(vGroup) );
504 Vec_IntShrink( vGroup, 1 );
505 break;
506 }
507*/
508 }
509}
510
522static inline void Gia_ManSimplifyXor( Vec_Int_t * vSuper )
523{
524 int i, k = 0, Prev = -1, This, fCompl = 0;
525 Vec_IntForEachEntry( vSuper, This, i )
526 {
527 if ( This == 0 )
528 continue;
529 if ( This == 1 )
530 fCompl ^= 1;
531 else if ( Prev != This )
532 Vec_IntWriteEntry( vSuper, k++, This ), Prev = This;
533 else
534 Prev = -1, k--;
535 }
536 Vec_IntShrink( vSuper, k );
537 if ( Vec_IntSize( vSuper ) == 0 )
538 Vec_IntPush( vSuper, fCompl );
539 else if ( fCompl )
540 Vec_IntWriteEntry( vSuper, 0, Abc_LitNot(Vec_IntEntry(vSuper, 0)) );
541}
542static inline void Gia_ManSimplifyAnd( Vec_Int_t * vSuper )
543{
544 int i, k = 0, Prev = -1, This;
545 Vec_IntForEachEntry( vSuper, This, i )
546 {
547 if ( This == 0 )
548 { Vec_IntFill(vSuper, 1, 0); return; }
549 if ( This == 1 )
550 continue;
551 if ( Prev == -1 || Abc_Lit2Var(Prev) != Abc_Lit2Var(This) )
552 Vec_IntWriteEntry( vSuper, k++, This ), Prev = This;
553 else if ( Prev != This )
554 { Vec_IntFill(vSuper, 1, 0); return; }
555 }
556 Vec_IntShrink( vSuper, k );
557 if ( Vec_IntSize( vSuper ) == 0 )
558 Vec_IntPush( vSuper, 1 );
559}
560
572static inline void Gia_ManSuperCollectXor_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
573{
574 assert( !Gia_IsComplement(pObj) );
575 if ( !Gia_ObjIsXor(pObj) ||
576 Gia_ObjRefNum(p, pObj) > 1 ||
577// Gia_ObjRefNum(p, pObj) > 3 ||
578// (Gia_ObjRefNum(p, pObj) == 2 && (Gia_ObjRefNum(p, Gia_ObjFanin0(pObj)) == 1 || Gia_ObjRefNum(p, Gia_ObjFanin1(pObj)) == 1)) ||
579 Vec_IntSize(p->vSuper) > STR_SUPER )
580 {
581 Vec_IntPush( p->vSuper, Gia_ObjToLit(p, pObj) );
582 return;
583 }
584 assert( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) );
585 Gia_ManSuperCollectXor_rec( p, Gia_ObjFanin0(pObj) );
586 Gia_ManSuperCollectXor_rec( p, Gia_ObjFanin1(pObj) );
587}
588static inline void Gia_ManSuperCollectAnd_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
589{
590 if ( Gia_IsComplement(pObj) ||
591 !Gia_ObjIsAndReal(p, pObj) ||
592 Gia_ObjRefNum(p, pObj) > 1 ||
593// Gia_ObjRefNum(p, pObj) > 3 ||
594// (Gia_ObjRefNum(p, pObj) == 2 && (Gia_ObjRefNum(p, Gia_ObjFanin0(pObj)) == 1 || Gia_ObjRefNum(p, Gia_ObjFanin1(pObj)) == 1)) ||
595 Vec_IntSize(p->vSuper) > STR_SUPER )
596 {
597 Vec_IntPush( p->vSuper, Gia_ObjToLit(p, pObj) );
598 return;
599 }
600 Gia_ManSuperCollectAnd_rec( p, Gia_ObjChild0(pObj) );
601 Gia_ManSuperCollectAnd_rec( p, Gia_ObjChild1(pObj) );
602}
603static inline void Gia_ManSuperCollect( Gia_Man_t * p, Gia_Obj_t * pObj )
604{
605 if ( p->vSuper == NULL )
606 p->vSuper = Vec_IntAlloc( STR_SUPER );
607 else
608 Vec_IntClear( p->vSuper );
609 if ( Gia_ObjIsXor(pObj) )
610 {
611 assert( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) );
612 Gia_ManSuperCollectXor_rec( p, Gia_ObjFanin0(pObj) );
613 Gia_ManSuperCollectXor_rec( p, Gia_ObjFanin1(pObj) );
614 Vec_IntSort( p->vSuper, 0 );
615 Gia_ManSimplifyXor( p->vSuper );
616 }
617 else if ( Gia_ObjIsAndReal(p, pObj) )
618 {
619 Gia_ManSuperCollectAnd_rec( p, Gia_ObjChild0(pObj) );
620 Gia_ManSuperCollectAnd_rec( p, Gia_ObjChild1(pObj) );
621 Vec_IntSort( p->vSuper, 0 );
622 Gia_ManSimplifyAnd( p->vSuper );
623 }
624 else assert( 0 );
625 assert( Vec_IntSize(p->vSuper) > 0 );
626}
627
639void Str_ManNormalize_rec( Str_Ntk_t * pNtk, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Wec_t * vGroups, Vec_Int_t * vRoots )
640{
641 int i, k, iVar, iLit, iBeg, iEnd;
642 if ( ~pObj->Value )
643 return;
644 pObj->Value = 0;
645 assert( Gia_ObjIsAnd(pObj) );
646 if ( Gia_ObjIsMux(p, pObj) )
647 {
648 Vec_Int_t * vGroup;
649 Gia_Obj_t * pRoot, * pMux;
650 int pFanins[3];
651 if ( Vec_IntEntry(vRoots, Gia_ObjId(p, pObj)) == -1 )
652 {
653 Str_ManNormalize_rec( pNtk, p, Gia_ObjFanin0(pObj), vGroups, vRoots );
654 Str_ManNormalize_rec( pNtk, p, Gia_ObjFanin1(pObj), vGroups, vRoots );
655 Str_ManNormalize_rec( pNtk, p, Gia_ObjFanin2(p, pObj), vGroups, vRoots );
656 pFanins[0] = Gia_ObjFanin0Copy(pObj);
657 pFanins[1] = Gia_ObjFanin1Copy(pObj);
658 pFanins[2] = Gia_ObjFanin2Copy(p, pObj);
659 if ( Abc_LitIsCompl(pFanins[2]) )
660 {
661 pFanins[2] = Abc_LitNot(pFanins[2]);
662 ABC_SWAP( int, pFanins[0], pFanins[1] );
663 }
664 pObj->Value = Str_ObjCreate( pNtk, STR_MUX, 3, pFanins );
665 return;
666 }
667 vGroup = Vec_WecEntry( vGroups, Vec_IntEntry(vRoots, Gia_ObjId(p, pObj)) );
668 // build data-inputs for each tree
669 Gia_ManForEachObjVec( vGroup, p, pRoot, i )
670 {
671 Str_MuxInputsCollect( p, pRoot, p->vSuper );
672 iBeg = Vec_IntSize( p->vStore );
673 Vec_IntAppend( p->vStore, p->vSuper );
674 iEnd = Vec_IntSize( p->vStore );
675 Vec_IntForEachEntryStartStop( p->vStore, iVar, k, iBeg, iEnd )
676 Str_ManNormalize_rec( pNtk, p, Gia_ManObj(p, iVar), vGroups, vRoots );
677 Vec_IntShrink( p->vStore, iBeg );
678 }
679 // build internal structures
680 Gia_ManForEachObjVec( vGroup, p, pRoot, i )
681 {
682 Str_MuxStructCollect( p, pRoot, p->vSuper );
683 Gia_ManForEachObjVec( p->vSuper, p, pMux, k )
684 {
685 pFanins[0] = Gia_ObjFanin0Copy(pMux);
686 pFanins[1] = Gia_ObjFanin1Copy(pMux);
687 pFanins[2] = Gia_ObjFanin2Copy(p, pMux);
688 if ( Abc_LitIsCompl(pFanins[2]) )
689 {
690 pFanins[2] = Abc_LitNot(pFanins[2]);
691 ABC_SWAP( int, pFanins[0], pFanins[1] );
692 }
693 pMux->Value = Str_ObjCreate( pNtk, STR_MUX, 3, pFanins );
694 }
695 assert( ~pRoot->Value );
696 // set mapping
697 Gia_ManForEachObjVec( p->vSuper, p, pMux, k )
698 Str_NtkObj(pNtk, Abc_Lit2Var(pMux->Value))->iTop = Abc_Lit2Var(pRoot->Value);
699 pNtk->nTrees++;
700 }
701 assert( ~pObj->Value );
702 // set mapping
703 pObj = Gia_ManObj( p, Vec_IntEntryLast(vGroup) );
704 Gia_ManForEachObjVec( vGroup, p, pRoot, i )
705 Str_NtkObj(pNtk, Abc_Lit2Var(pRoot->Value))->iTop = Abc_Lit2Var(pObj->Value);
706 pNtk->nGroups++;
707 //printf( "%d x %d ", Vec_IntSize(vGroup), Vec_IntSize(p->vSuper) );
708 return;
709 }
710 // find supergate
711 Gia_ManSuperCollect( p, pObj );
712 // save entries
713 iBeg = Vec_IntSize( p->vStore );
714 Vec_IntAppend( p->vStore, p->vSuper );
715 iEnd = Vec_IntSize( p->vStore );
716 // call recursively
717 Vec_IntForEachEntryStartStop( p->vStore, iLit, i, iBeg, iEnd )
718 {
719 Gia_Obj_t * pTemp = Gia_ManObj( p, Abc_Lit2Var(iLit) );
720 Str_ManNormalize_rec( pNtk, p, pTemp, vGroups, vRoots );
721 Vec_IntWriteEntry( p->vStore, i, Abc_LitNotCond(pTemp->Value, Abc_LitIsCompl(iLit)) );
722 }
723 assert( Vec_IntSize(p->vStore) == iEnd );
724 // consider general case
725 pObj->Value = Str_ObjCreate( pNtk, Gia_ObjIsXor(pObj) ? STR_XOR : STR_AND, iEnd-iBeg, Vec_IntEntryP(p->vStore, iBeg) );
726 Vec_IntShrink( p->vStore, iBeg );
727}
729{
730 Str_Ntk_t * pNtk;
731 Gia_Obj_t * pObj;
732 int i, iFanin;
733 assert( p->pMuxes != NULL );
734 if ( p->vSuper == NULL )
735 p->vSuper = Vec_IntAlloc( STR_SUPER );
736 if ( p->vStore == NULL )
737 p->vStore = Vec_IntAlloc( STR_SUPER );
739 pNtk = Str_NtkCreate( Gia_ManObjNum(p) + 10000, 1 + Gia_ManCoNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManMuxNum(p) + 10000 );
740 Gia_ManConst0(p)->Value = 0;
741 Gia_ManForEachObj1( p, pObj, i )
742 {
743 if ( Gia_ObjIsCi(pObj) )
744 pObj->Value = Str_ObjCreate( pNtk, STR_PI, 0, NULL );
745 else if ( Gia_ObjIsCo(pObj) )
746 {
747 Str_ManNormalize_rec( pNtk, p, Gia_ObjFanin0(pObj), vGroups, vRoots );
748 iFanin = Gia_ObjFanin0Copy(pObj);
749 pObj->Value = Str_ObjCreate( pNtk, STR_PO, 1, &iFanin );
750 }
751 }
752 //assert( pNtk->nObjs <= Gia_ManObjNum(p) );
753 return pNtk;
754}
756{
757 Str_Ntk_t * pNtk;
758 Gia_Man_t * pMuxes = Gia_ManDupMuxes( p, 5 );
759 Vec_Wec_t * vGroups = Str_ManDeriveTrees( pMuxes );
760 Vec_Int_t * vRoots;
761 Str_ManCheckOverlap( pMuxes, vGroups );
762 vRoots = Str_ManCreateRoots( vGroups, Gia_ManObjNum(pMuxes) );
763 pNtk = Str_ManNormalizeInt( pMuxes, vGroups, vRoots );
764 Gia_ManCleanMark0( pMuxes );
765 Gia_ManStop( pMuxes );
766 Vec_IntFree( vRoots );
767 Vec_WecFree( vGroups );
768 return pNtk;
769}
770
782static inline int Str_Delay2( int d0, int d1, int nLutSize )
783{
784 int n, d = Abc_MaxInt( d0 >> 4, d1 >> 4 );
785 n = (d == (d0 >> 4)) ? (d0 & 15) : 1;
786 n += (d == (d1 >> 4)) ? (d1 & 15) : 1;
787 return (d << 4) + (n > nLutSize ? 18 : n);
788}
789static inline int Str_Delay3( int d0, int d1, int d2, int nLutSize )
790{
791 int n, d = Abc_MaxInt( Abc_MaxInt(d0 >> 4, d1 >> 4), d2 >> 4 );
792 n = (d == (d0 >> 4)) ? (d0 & 15) : 1;
793 n += (d == (d1 >> 4)) ? (d1 & 15) : 1;
794 n += (d == (d2 >> 4)) ? (d2 & 15) : 1;
795 return (d << 4) + (n > nLutSize ? 19 : n);
796}
797static inline int Str_ObjDelay( Gia_Man_t * pNew, int iObj, int nLutSize, Vec_Int_t * vDelay )
798{
799 int Delay = Vec_IntEntry( vDelay, iObj );
800 if ( Delay == 0 )
801 {
802 if ( Gia_ObjIsMuxId(pNew, iObj) )
803 {
804 int d0 = Vec_IntEntry( vDelay, Gia_ObjFaninId0(Gia_ManObj(pNew, iObj), iObj) );
805 int d1 = Vec_IntEntry( vDelay, Gia_ObjFaninId1(Gia_ManObj(pNew, iObj), iObj) );
806 int d2 = Vec_IntEntry( vDelay, Gia_ObjFaninId2(pNew, iObj) );
807 Delay = Str_Delay3( d0, d1, d2, nLutSize );
808 }
809 else
810 {
811 int d0 = Vec_IntEntry( vDelay, Gia_ObjFaninId0(Gia_ManObj(pNew, iObj), iObj) );
812 int d1 = Vec_IntEntry( vDelay, Gia_ObjFaninId1(Gia_ManObj(pNew, iObj), iObj) );
813 Delay = Str_Delay2( d0, d1, nLutSize );
814 }
815 Vec_IntWriteEntry( vDelay, iObj, Delay );
816 }
817 return Delay;
818}
819
820
821
833static inline void transpose64( word A[64] )
834{
835 int j, k;
836 word t, m = 0x00000000FFFFFFFF;
837 for ( j = 32; j != 0; j = j >> 1, m = m ^ (m << j) )
838 {
839 for ( k = 0; k < 64; k = (k + j + 1) & ~j )
840 {
841 t = (A[k] ^ (A[k+j] >> j)) & m;
842 A[k] = A[k] ^ t;
843 A[k+j] = A[k+j] ^ (t << j);
844 }
845 }
846}
847
859static inline int Str_ManNum( Gia_Man_t * p, int iObj ) { return Vec_IntEntry(&p->vCopies, iObj); }
860static inline void Str_ManSetNum( Gia_Man_t * p, int iObj, int Num ) { Vec_IntWriteEntry(&p->vCopies, iObj, Num); }
861
862int Str_ManVectorAffinity( Gia_Man_t * p, Vec_Int_t * vSuper, Vec_Int_t * vDelay, word * Matrix, int nLimit )
863{
864 int fVerbose = 0;
865 int * Levels = NULL;
866 int nSize = Vec_IntSize(vSuper);
867 int Prev = nSize, nLevels = 1;
868 int i, k, iLit, iFanin, nSizeNew;
869 word Mask;
870 assert( nSize > 2 );
871 assert( nSize <= nLimit );
872 if ( nSize > 64 )
873 {
874 for ( i = 0; i < 64; i++ )
875 Matrix[i] = 0;
876 return 0;
877 }
878 Levels = ABC_ALLOC( int, nLimit+256 );
879 // mark current nodes
881 Vec_IntForEachEntry( vSuper, iLit, i )
882 {
883 Gia_ObjSetTravIdCurrentId( p, Abc_Lit2Var(iLit) );
884 Str_ManSetNum( p, Abc_Lit2Var(iLit), i );
885 Matrix[i] = ((word)1) << (63-i);
886 Levels[i] = 0;
887 }
888 // collect 64 nodes
889 Vec_IntForEachEntry( vSuper, iLit, i )
890 {
891 Gia_Obj_t * pObj = Gia_ManObj( p, Abc_Lit2Var(iLit) );
892 if ( Gia_ObjIsAnd(pObj) )
893 {
894 for ( k = 0; k < 2; k++ )
895 {
896 iFanin = k ? Gia_ObjFaninId1p(p, pObj) : Gia_ObjFaninId0p(p, pObj);
897 if ( !Gia_ObjIsTravIdCurrentId(p, iFanin) )
898 {
899 if ( Vec_IntSize(vSuper) == nLimit )
900 break;
901 Gia_ObjSetTravIdCurrentId( p, iFanin );
902 Matrix[Vec_IntSize(vSuper)] = 0;
903 Levels[Vec_IntSize(vSuper)] = nLevels;
904 Str_ManSetNum( p, iFanin, Vec_IntSize(vSuper) );
905 Vec_IntPush( vSuper, Abc_Var2Lit(iFanin, 0) );
906 }
907 Matrix[Str_ManNum(p, iFanin)] |= Matrix[i];
908 }
909 }
910 if ( Gia_ObjIsMux(p, pObj) )
911 {
912 iFanin = Gia_ObjFaninId2p(p, pObj);
913 if ( !Gia_ObjIsTravIdCurrentId(p, iFanin) )
914 {
915 if ( Vec_IntSize(vSuper) == nLimit )
916 break;
917 Gia_ObjSetTravIdCurrentId( p, iFanin );
918 Matrix[Vec_IntSize(vSuper)] = 0;
919 Levels[Vec_IntSize(vSuper)] = nLevels;
920 Str_ManSetNum( p, iFanin, Vec_IntSize(vSuper) );
921 Vec_IntPush( vSuper, Abc_Var2Lit(iFanin, 0) );
922 }
923 Matrix[Str_ManNum(p, iFanin)] |= Matrix[i];
924 }
925 if ( Prev == i )
926 Prev = Vec_IntSize(vSuper), nLevels++;
927 if ( nLevels == 8 )
928 break;
929 }
930
931 // remove those that have all 1s or only one 1
932 Mask = (~(word)0) << (64 - nSize);
933 for ( k = i = 0; i < Vec_IntSize(vSuper); i++ )
934 {
935 assert( Matrix[i] );
936 if ( (Matrix[i] & (Matrix[i] - 1)) == 0 )
937 continue;
938 if ( Matrix[i] == Mask )
939 continue;
940 Matrix[k] = Matrix[i];
941 Levels[k] = Levels[i];
942 k++;
943 if ( k == 64 )
944 break;
945 }
946 // clean the remaining ones
947 for ( i = k; i < 64; i++ )
948 Matrix[i] = 0;
949 nSizeNew = k;
950 if ( nSizeNew == 0 )
951 {
952 Vec_IntShrink( vSuper, nSize );
953 ABC_FREE( Levels );
954 return 0;
955 }
956/*
957 // report
958 if ( fVerbose && nSize > 20 )
959 {
960 for ( i = 0; i < nSizeNew; i++ )
961 Extra_PrintBinary( stdout, Matrix+i, 64 ), printf( "\n" );
962 printf( "\n" );
963 }
964*/
965 transpose64( Matrix );
966
967 // report
968 if ( fVerbose && nSize > 10 )
969 {
970 printf( "Gate inputs = %d. Collected fanins = %d. All = %d. Good = %d. Levels = %d\n",
971 nSize, Vec_IntSize(vSuper) - nSize, Vec_IntSize(vSuper), nSizeNew, nLevels );
972 printf( " " );
973 for ( i = 0; i < nSizeNew; i++ )
974 printf( "%d", Levels[i] );
975 printf( "\n" );
976 for ( i = 0; i < nSize; i++ )
977 {
978 printf( "%6d : ", Abc_Lit2Var(Vec_IntEntry(vSuper, i)) );
979 printf( "%3d ", Vec_IntEntry(vDelay, i) >> 4 );
980 printf( "%3d ", Vec_IntEntry(vDelay, i) & 15 );
981// Extra_PrintBinary( stdout, Matrix+i, 64 ), printf( "\n" );
982 }
983 i = 0;
984 }
985 ABC_FREE( Levels );
986 Vec_IntShrink( vSuper, nSize );
987 return nSizeNew;
988}
989
1001static inline int Str_CountBits( word i )
1002{
1003 if ( i == 0 )
1004 return 0;
1005 i = (i & (i - 1));
1006 if ( i == 0 )
1007 return 1;
1008 i = (i & (i - 1));
1009 if ( i == 0 )
1010 return 2;
1011 i = i - ((i >> 1) & 0x5555555555555555);
1012 i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333);
1013 i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F);
1014 return (i*(0x0101010101010101))>>56;
1015}
1016
1017static inline void Str_PrintState( int * pCost, int * pSuper, word * pMatrix, int nSize )
1018{
1019 int i;
1020 for ( i = 0; i < nSize; i++ )
1021 {
1022 printf( "%6d : ", i );
1023 printf( "%6d : ", Abc_Lit2Var(pSuper[i]) );
1024 printf( "%3d ", pCost[i] >> 4 );
1025 printf( "%3d ", pCost[i] & 15 );
1026// Extra_PrintBinary( stdout, pMatrix+i, 64 ), printf( "\n" );
1027 }
1028 printf( "\n" );
1029}
1030
1031
1043void Str_NtkBalanceMulti2( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec_Int_t * vDelay, int nLutSize )
1044{
1045 int k;
1046 pObj->iCopy = (pObj->Type == STR_AND);
1047 for ( k = 0; k < (int)pObj->nFanins; k++ )
1048 {
1049 if ( pObj->Type == STR_AND )
1050 pObj->iCopy = Gia_ManHashAnd( pNew, pObj->iCopy, Str_ObjFaninCopy(p, pObj, k) );
1051 else
1052 pObj->iCopy = Gia_ManHashXorReal( pNew, pObj->iCopy, Str_ObjFaninCopy(p, pObj, k) );
1053 Str_ObjDelay( pNew, Abc_Lit2Var(pObj->iCopy), nLutSize, vDelay );
1054 }
1055}
1056
1057int Str_NtkBalanceTwo( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, int i, int j, Vec_Int_t * vDelay, int * pCost, int * pSuper, word * pMatrix, int nSize, int nLutSize, int CostBest )
1058{
1059 int k, iLitRes, Delay;
1060 assert( i < j );
1061// printf( "Merging node %d and %d\n", i, j );
1062 if ( pObj->Type == STR_AND )
1063 iLitRes = Gia_ManHashAnd( pNew, pSuper[i], pSuper[j] );
1064 else
1065 iLitRes = Gia_ManHashXorReal( pNew, pSuper[i], pSuper[j] );
1066 Delay = Str_ObjDelay( pNew, Abc_Lit2Var(iLitRes), nLutSize, vDelay );
1067 // update
1068 pCost[i] = Delay;
1069 pSuper[i] = iLitRes;
1070 pMatrix[i] |= pMatrix[j];
1071// assert( (pCost[i] & 15) == CostBest || CostBest == -1 );
1072 // remove entry j
1073 nSize--;
1074 for ( k = j; k < nSize; k++ )
1075 {
1076 pCost[k] = pCost[k+1];
1077 pSuper[k] = pSuper[k+1];
1078 pMatrix[k] = pMatrix[k+1];
1079 }
1080 // move up the first one
1081 nSize--;
1082 for ( k = 0; k < nSize; k++ )
1083 {
1084 if ( pCost[k] <= pCost[k+1] )
1085 break;
1086 ABC_SWAP( int, pCost[k], pCost[k+1] );
1087 ABC_SWAP( int, pSuper[k], pSuper[k+1] );
1088 ABC_SWAP( word, pMatrix[k], pMatrix[k+1] );
1089 }
1090 return iLitRes;
1091}
1092
1093void Str_NtkBalanceMulti( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec_Int_t * vDelay, int nLutSize )
1094{
1095 word * pMatrix = ABC_ALLOC( word, pObj->nFanins+256 );
1096 Vec_Int_t * vSuper = pNew->vSuper;
1097 Vec_Int_t * vCosts = pNew->vStore;
1098 int * pSuper = Vec_IntArray(vSuper);
1099 int * pCost = Vec_IntArray(vCosts);
1100 int k, iLit, MatrixSize = 0;
1101 assert( (int)pObj->nFanins <= Vec_IntCap(vSuper) );
1102 assert( (int)pObj->nFanins <= Vec_IntCap(vCosts) );
1103
1104 // collect nodes
1105 Vec_IntClear( vSuper );
1106 for ( k = 0; k < (int)pObj->nFanins; k++ )
1107 Vec_IntPush( vSuper, Str_ObjFaninCopy(p, pObj, k) );
1108 Vec_IntSort( vSuper, 0 );
1109 if ( pObj->Type == STR_AND )
1110 Gia_ManSimplifyAnd( vSuper );
1111 else
1112 Gia_ManSimplifyXor( vSuper );
1113 assert( Vec_IntSize(vSuper) > 0 );
1114 if ( Vec_IntSize(vSuper) == 1 )
1115 {
1116 pObj->iCopy = Vec_IntEntry(vSuper, 0);
1117 ABC_FREE( pMatrix );
1118 return;
1119 }
1120 if ( Vec_IntSize(vSuper) == 2 )
1121 {
1122 pObj->iCopy = Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, 2, nLutSize, -1 );
1123 ABC_FREE( pMatrix );
1124 return;
1125 }
1126
1127 // sort by cost
1128 Vec_IntClear( vCosts );
1129 Vec_IntForEachEntry( vSuper, iLit, k )
1130 Vec_IntPush( vCosts, Vec_IntEntry(vDelay, Abc_Lit2Var(iLit)) );
1131 Vec_IntSelectSortCost2( pSuper, Vec_IntSize(vSuper), pCost );
1132
1133 // compute affinity
1134 if ( Vec_IntSize(vSuper) < 64 )
1135 MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, pObj->nFanins );
1136
1137 // start the new product
1138 while ( Vec_IntSize(vSuper) > 2 )
1139 {
1140 // pair the first entry with another one on the same level
1141 int i, iStop, iBest,iBest2;
1142 int CostNew, CostBest, CostBest2;
1143 int OccurNew, OccurBest, OccurBest2;
1144
1145 if ( Vec_IntSize(vSuper) > 64 )
1146 {
1147 Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, Vec_IntSize(vSuper), nLutSize, -1 );
1148 vSuper->nSize--;
1149 vCosts->nSize--;
1150 continue;
1151 }
1152
1153 // compute affinity
1154 if ( Vec_IntSize(vSuper) == 64 )
1155 MatrixSize = Str_ManVectorAffinity( pNew, vSuper, vCosts, pMatrix, pObj->nFanins );
1156 assert( Vec_IntSize(vSuper) <= 64 );
1157// Str_PrintState( pCost, pSuper, pMatrix, Vec_IntSize(vSuper) );
1158
1159 // if the first two are PIs group them
1160 if ( pCost[0] == 17 && pCost[1] == 17 )
1161 {
1162 Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, Vec_IntSize(vSuper), nLutSize, 2 );
1163 vSuper->nSize--;
1164 vCosts->nSize--;
1165 continue;
1166 }
1167
1168 // find the end of the level
1169 for ( iStop = 0; iStop < Vec_IntSize(vSuper); iStop++ )
1170 if ( (pCost[iStop] >> 4) != (pCost[0] >> 4) )
1171 break;
1172 // if there is only one this level, pair it with the best match in the next level
1173 if ( iStop == 1 )
1174 {
1175 iBest = iStop, OccurBest = Str_CountBits(pMatrix[0] & pMatrix[iStop]);
1176 for ( i = iStop + 1; i < Vec_IntSize(vSuper); i++ )
1177 {
1178 if ( (pCost[i] >> 4) != (pCost[iStop] >> 4) )
1179 break;
1180 OccurNew = Str_CountBits(pMatrix[0] & pMatrix[i]);
1181 if ( OccurBest < OccurNew )
1182 iBest = i, OccurBest = OccurNew;
1183 }
1184 assert( iBest > 0 && iBest < Vec_IntSize(vSuper) );
1185 Str_NtkBalanceTwo( pNew, p, pObj, 0, iBest, vDelay, pCost, pSuper, pMatrix, Vec_IntSize(vSuper), nLutSize, -1 );
1186 vSuper->nSize--;
1187 vCosts->nSize--;
1188 continue;
1189 }
1190 // pair the first entry with another one on the same level
1191 iBest = -1; CostBest = -1; OccurBest2 = -1; OccurBest = -1;
1192 for ( i = 1; i < iStop; i++ )
1193 {
1194 CostNew = (pCost[0] & 15) + (pCost[i] & 15);
1195 if ( CostNew > nLutSize )
1196 continue;
1197 OccurNew = Str_CountBits(pMatrix[0] & pMatrix[i]);
1198 if ( CostBest < CostNew || (CostBest == CostNew && OccurBest < OccurNew) )
1199 CostBest = CostNew, iBest = i, OccurBest = OccurNew;
1200 }
1201 // if the best found is perfect, take it
1202 if ( CostBest == nLutSize )
1203 {
1204 assert( iBest > 0 && iBest < Vec_IntSize(vSuper) );
1205 Str_NtkBalanceTwo( pNew, p, pObj, 0, iBest, vDelay, pCost, pSuper, pMatrix, Vec_IntSize(vSuper), nLutSize, CostBest );
1206 vSuper->nSize--;
1207 vCosts->nSize--;
1208 continue;
1209 }
1210 // find the best pair on this level
1211 iBest = iBest2 = -1; CostBest = CostBest2 = -1, OccurBest = OccurBest2 = -1;
1212 for ( i = 0; i < iStop; i++ )
1213 for ( k = i+1; k < iStop; k++ )
1214 {
1215 CostNew = (pCost[i] & 15) + (pCost[k] & 15);
1216 OccurNew = Str_CountBits(pMatrix[i] & pMatrix[k]);
1217 if ( CostNew <= nLutSize ) // the same level
1218 {
1219 if ( OccurBest < OccurNew || (OccurBest == OccurNew && CostBest < CostNew ))
1220 CostBest = CostNew, iBest = (i << 16) | k, OccurBest = OccurNew;
1221 }
1222 else // overflow to the next level
1223 {
1224 if ( OccurBest2 < OccurNew || (OccurBest2 == OccurNew && CostBest2 < CostNew) )
1225 CostBest2 = CostNew, iBest2 = (i << 16) | k, OccurBest2 = OccurNew;
1226 }
1227 }
1228 if ( iBest >= 0 )
1229 {
1230 assert( iBest > 0 );
1231 Str_NtkBalanceTwo( pNew, p, pObj, iBest>>16, iBest&0xFFFF, vDelay, pCost, pSuper, pMatrix, Vec_IntSize(vSuper), nLutSize, CostBest );
1232 vSuper->nSize--;
1233 vCosts->nSize--;
1234 continue;
1235 }
1236 // take any remaining pair
1237 assert( iBest2 > 0 );
1238 Str_NtkBalanceTwo( pNew, p, pObj, iBest2>>16, iBest2&0xFFFF, vDelay, pCost, pSuper, pMatrix, Vec_IntSize(vSuper), nLutSize, -1 );
1239 vSuper->nSize--;
1240 vCosts->nSize--;
1241 continue;
1242 }
1243 pObj->iCopy = Str_NtkBalanceTwo( pNew, p, pObj, 0, 1, vDelay, pCost, pSuper, pMatrix, 2, nLutSize, -1 );
1244 ABC_FREE( pMatrix );
1245
1246/*
1247 // simple
1248 pObj->iCopy = (pObj->Type == STR_AND);
1249 for ( k = 0; k < Vec_IntSize(vSuper); k++ )
1250 {
1251 if ( pObj->Type == STR_AND )
1252 pObj->iCopy = Gia_ManHashAnd( pNew, pObj->iCopy, Vec_IntEntry(vSuper, k) );
1253 else
1254 pObj->iCopy = Gia_ManHashXorReal( pNew, pObj->iCopy, Vec_IntEntry(vSuper, k) );
1255 Str_ObjDelay( pNew, Abc_Lit2Var(pObj->iCopy), nLutSize, vDelay );
1256 }
1257*/
1258}
1259void Str_NtkBalanceMux( Gia_Man_t * pNew, Str_Ntk_t * p, Str_Obj_t * pObj, Vec_Int_t * vDelay, int nLutSize, int nGroups, int nMuxes, int fRecursive, int fOptArea, int fVerbose )
1260{
1261 extern int Str_MuxRestructure( Gia_Man_t * pNew, Str_Ntk_t * pNtk, int iMux, int nMuxes, Vec_Int_t * vDelay, int nLutSize, int fRecursive, int fOptArea, int fVerbose );
1262 int n, m, iRes, fUseRestruct = 1;
1263 if ( fUseRestruct )
1264 {
1265 for ( n = 0; n < nGroups; n++ )
1266 {
1267 iRes = Str_MuxRestructure( pNew, p, Str_ObjId(p, pObj), nMuxes, vDelay, nLutSize, fRecursive, fOptArea, fVerbose );
1268 if ( iRes == -1 )
1269 {
1270 for ( m = 0; m < nMuxes; m++, pObj++ )
1271 {
1272 pObj->iCopy = Gia_ManHashMuxReal( pNew, Str_ObjFaninCopy(p, pObj, 2), Str_ObjFaninCopy(p, pObj, 1), Str_ObjFaninCopy(p, pObj, 0) );
1273 Str_ObjDelay( pNew, Abc_Lit2Var(pObj->iCopy), nLutSize, vDelay );
1274 }
1275 }
1276 else
1277 {
1278 pObj += nMuxes - 1;
1279 pObj->iCopy = iRes;
1280 pObj++;
1281 }
1282 }
1283 }
1284 else
1285 {
1286 for ( n = 0; n < nGroups * nMuxes; n++, pObj++ )
1287 {
1288 pObj->iCopy = Gia_ManHashMuxReal( pNew, Str_ObjFaninCopy(p, pObj, 2), Str_ObjFaninCopy(p, pObj, 1), Str_ObjFaninCopy(p, pObj, 0) );
1289 Str_ObjDelay( pNew, Abc_Lit2Var(pObj->iCopy), nLutSize, vDelay );
1290 }
1291 }
1292}
1293Gia_Man_t * Str_NtkBalance( Gia_Man_t * pGia, Str_Ntk_t * p, int nLutSize, int fUseMuxes, int fRecursive, int fOptArea, int fVerbose )
1294{
1295 Gia_Man_t * pNew, * pTemp;
1296 Vec_Int_t * vDelay;
1297 Str_Obj_t * pObj;
1298 int nGroups, nMuxes, CioId;
1299 int arrTime, Delay = 0;
1300 assert( nLutSize < 16 );
1301 assert( pGia->pMuxes == NULL );
1302 pNew = Gia_ManStart( Gia_ManObjNum(pGia) );
1303 pNew->pName = Abc_UtilStrsav( pGia->pName );
1304 pNew->pSpec = Abc_UtilStrsav( pGia->pSpec );
1305 pNew->pMuxes = ABC_CALLOC( unsigned, pNew->nObjsAlloc );
1306 Vec_IntFill( &pNew->vCopies, pNew->nObjsAlloc, -1 );
1307 if ( pNew->vSuper == NULL )
1308 pNew->vSuper = Vec_IntAlloc( 1000 );
1309 if ( pNew->vStore == NULL )
1310 pNew->vStore = Vec_IntAlloc( 1000 );
1311 vDelay = Vec_IntStart( 2*pNew->nObjsAlloc );
1312 Gia_ManHashStart( pNew );
1313 if ( pGia->pManTime != NULL ) // Tim_Man with unit delay 16
1314 {
1317 }
1318 Str_NtkManForEachObj( p, pObj )
1319 {
1320 if ( pObj->Type == STR_PI )
1321 {
1322 pObj->iCopy = Gia_ManAppendCi( pNew );
1323 arrTime = 17;
1324 if ( pGia->pManTime != NULL )
1325 {
1326 CioId = Gia_ObjCioId( Gia_ManObj(pNew, Abc_Lit2Var(pObj->iCopy)) );
1327 arrTime = (int)Tim_ManGetCiArrival( (Tim_Man_t *)pGia->pManTime, CioId );
1328 }
1329 Vec_IntWriteEntry( vDelay, Abc_Lit2Var(pObj->iCopy), arrTime );
1330 }
1331 else if ( pObj->Type == STR_AND || pObj->Type == STR_XOR )
1332 Str_NtkBalanceMulti( pNew, p, pObj, vDelay, nLutSize );
1333 else if ( pObj->Type == STR_MUX && pObj->iTop >= 0 && fUseMuxes )
1334 {
1335 Str_ObjReadGroup( p, pObj, &nGroups, &nMuxes );
1336 assert( nGroups * nMuxes >= 2 );
1337 Str_NtkBalanceMux( pNew, p, pObj, vDelay, nLutSize, nGroups, nMuxes, fRecursive, fOptArea, fVerbose );
1338 pObj += nGroups * nMuxes - 1;
1339 }
1340 else if ( pObj->Type == STR_MUX )
1341 {
1342 pObj->iCopy = Gia_ManHashMuxReal( pNew, Str_ObjFaninCopy(p, pObj, 2), Str_ObjFaninCopy(p, pObj, 1), Str_ObjFaninCopy(p, pObj, 0) );
1343 Str_ObjDelay( pNew, Abc_Lit2Var(pObj->iCopy), nLutSize, vDelay );
1344 }
1345 else if ( pObj->Type == STR_PO )
1346 {
1347 pObj->iCopy = Gia_ManAppendCo( pNew, Str_ObjFaninCopy(p, pObj, 0) );
1348 arrTime = Vec_IntEntry(vDelay, Abc_Lit2Var(Str_ObjFaninCopy(p, pObj, 0)) );
1349 Delay = Abc_MaxInt( Delay, arrTime );
1350 if ( pGia->pManTime != NULL )
1351 {
1352 CioId = Gia_ObjCioId( Gia_ManObj(pNew, Abc_Lit2Var(pObj->iCopy)) );
1353 Tim_ManSetCoArrival( (Tim_Man_t *)pGia->pManTime, CioId, (float)arrTime );
1354 }
1355 }
1356 else if ( pObj->Type == STR_CONST0 )
1357 pObj->iCopy = 0, Vec_IntWriteEntry(vDelay, 0, 17);
1358 else assert( 0 );
1359 }
1360 if ( fVerbose )
1361 printf( "Max delay = %d. Old objs = %d. New objs = %d.\n", Delay >> 4, Gia_ManObjNum(pGia), Gia_ManObjNum(pNew) );
1362 Vec_IntFree( vDelay );
1363 ABC_FREE( pNew->vCopies.pArray );
1364 Gia_ManHashStop( pNew );
1365 Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia) );
1366 pNew = Gia_ManDupNoMuxes( pTemp = pNew, 0 );
1367 Gia_ManStop( pTemp );
1368// if ( pGia->pManTime != NULL )
1369// pNew->pManTime = Tim_ManDup( (Tim_Man_t *)pGia->pManTime, 0 );
1370 return pNew;
1371}
1372
1384Gia_Man_t * Gia_ManLutBalance( Gia_Man_t * p, int nLutSize, int fUseMuxes, int fRecursive, int fOptArea, int fVerbose )
1385{
1386 Str_Ntk_t * pNtk;
1387 Gia_Man_t * pNew;
1388 abctime clk = Abc_Clock();
1389 if ( p->pManTime && Tim_ManBoxNum((Tim_Man_t*)p->pManTime) && Gia_ManIsNormalized(p) )
1390 {
1391 Tim_Man_t * pTimOld = (Tim_Man_t *)p->pManTime;
1392 p->pManTime = Tim_ManDup( pTimOld, 16 );
1393 pNew = Gia_ManDupUnnormalize( p );
1394 if ( pNew == NULL )
1395 return NULL;
1396 Gia_ManTransferTiming( pNew, p );
1397 p = pNew;
1398 // optimize
1399 pNtk = Str_ManNormalize( p );
1400 pNew = Str_NtkBalance( p, pNtk, nLutSize, fUseMuxes, fRecursive, fOptArea, fVerbose );
1401 Gia_ManTransferTiming( pNew, p );
1402 Gia_ManStop( p );
1403 // normalize
1404 pNew = Gia_ManDupNormalize( p = pNew, 0 );
1405 Gia_ManTransferTiming( pNew, p );
1406 Gia_ManStop( p );
1407 // cleanup
1408 Tim_ManStop( (Tim_Man_t *)pNew->pManTime );
1409 pNew->pManTime = pTimOld;
1410 assert( Gia_ManIsNormalized(pNew) );
1411 }
1412 else
1413 {
1414 pNtk = Str_ManNormalize( p );
1415 // Str_NtkPrintGroups( pNtk );
1416 pNew = Str_NtkBalance( p, pNtk, nLutSize, fUseMuxes, fRecursive, fOptArea, fVerbose );
1417 Gia_ManTransferTiming( pNew, p );
1418 }
1419 if ( fVerbose )
1420 Str_NtkPs( pNtk, Abc_Clock() - clk );
1421 Str_NtkDelete( pNtk );
1422 return pNew;
1423}
1424
1425
1426
1427
1428
1440typedef struct Str_Edg_t_ Str_Edg_t;
1442{
1443 int Fan; // fanin ID
1444 int fCompl; // fanin complement
1445 int FanDel; // fanin delay
1446 int Copy; // fanin copy
1447};
1448
1449typedef struct Str_Mux_t_ Str_Mux_t; // 64 bytes
1451{
1452 int Id; // node ID
1453 int Delay; // node delay
1454 int Copy; // node copy
1455 int nLutSize; // LUT size
1456 Str_Edg_t Edge[3]; // fanins
1457};
1458
1459static inline Str_Mux_t * Str_MuxFanin( Str_Mux_t * pMux, int i ) { return pMux - pMux->Id + pMux->Edge[i].Fan; }
1460static inline int Str_MuxHasFanin( Str_Mux_t * pMux, int i ) { return pMux->Edge[i].Fan > 0 && Str_MuxFanin(pMux, i)->Copy != -2; }
1461
1463{
1464 int fShowDelay = 1;
1465 Str_Mux_t * pFanin;
1466 if ( pMux->Edge[i].Fan <= 0 )
1467 {
1468 printf( "%d", -pMux->Edge[i].Fan );
1469 if ( fShowDelay )
1470 printf( "{%d}", pMux->Edge[i].FanDel );
1471 return;
1472 }
1473 pFanin = Str_MuxFanin( pMux, i );
1474 printf( "[ " );
1475 if ( pFanin->Edge[0].fCompl )
1476 printf( "!" );
1477 Str_MuxDelayPrint_rec( pFanin, 0 );
1478 printf( "|" );
1479 if ( pFanin->Edge[1].fCompl )
1480 printf( "!" );
1481 Str_MuxDelayPrint_rec( pFanin, 1 );
1482 printf( "(" );
1483 if ( pFanin->Edge[2].fCompl )
1484 printf( "!" );
1485 Str_MuxDelayPrint_rec( pFanin, 2 );
1486 printf( ")" );
1487 printf( " ]" );
1488}
1490{
1491 if ( pMux->Edge[i].Fan > 0 )
1492 {
1493 Str_Mux_t * pFanin = Str_MuxFanin( pMux, i );
1494 Str_MuxDelayEdge_rec( pFanin, 0 );
1495 Str_MuxDelayEdge_rec( pFanin, 1 );
1496 pMux->Edge[i].FanDel = Str_Delay3( pFanin->Edge[0].FanDel, pFanin->Edge[1].FanDel, pFanin->Edge[2].FanDel, pFanin->nLutSize );
1497 }
1498 return pMux->Edge[i].FanDel;
1499}
1500void Str_MuxCreate( Str_Mux_t * pTree, Str_Ntk_t * pNtk, int iMux, int nMuxes, Vec_Int_t * vDelay, int nLutSize )
1501{
1502 Str_Obj_t * pObj;
1503 Str_Mux_t * pMux;
1504 int i, k, nPis = 0;
1505 assert( nMuxes >= 2 );
1506 memset( pTree, 0, sizeof(Str_Mux_t) * (nMuxes + 1) );
1507 pTree->nLutSize = nLutSize;
1508 pTree->Edge[0].Fan = 1;
1509 for ( i = 1; i <= nMuxes; i++ )
1510 {
1511 pMux = pTree + i;
1512 pMux->Id = i;
1513 pMux->nLutSize = nLutSize;
1514 pMux->Delay = pMux->Copy = -1;
1515 // assign fanins
1516 pObj = Str_NtkObj( pNtk, iMux + nMuxes - i );
1517 assert( pObj->Type == STR_MUX );
1518 for ( k = 0; k < 3; k++ )
1519 {
1520 pMux->Edge[k].fCompl = Str_ObjFaninC(pNtk, pObj, k);
1521 if ( Str_ObjFaninId(pNtk, pObj, k) >= iMux )
1522 pMux->Edge[k].Fan = iMux + nMuxes - Str_ObjFaninId(pNtk, pObj, k);
1523 else
1524 {
1525 pMux->Edge[k].Fan = -nPis++; // count external inputs, including controls
1526 pMux->Edge[k].Copy = Str_ObjFanin(pNtk, pObj, k)->iCopy;
1527 pMux->Edge[k].FanDel = Vec_IntEntry( vDelay, Abc_Lit2Var(pMux->Edge[k].Copy) );
1528 }
1529 }
1530 }
1531}
1532int Str_MuxToGia_rec( Gia_Man_t * pNew, Str_Mux_t * pMux, int i, Vec_Int_t * vDelay )
1533{
1534 if ( pMux->Edge[i].Fan > 0 )
1535 {
1536 Str_Mux_t * pFanin = Str_MuxFanin( pMux, i );
1537 int iLit0 = Str_MuxToGia_rec( pNew, pFanin, 0, vDelay );
1538 int iLit1 = Str_MuxToGia_rec( pNew, pFanin, 1, vDelay );
1539 assert( pFanin->Edge[2].Fan <= 0 );
1540 assert( pFanin->Edge[2].fCompl == 0 );
1541 pMux->Edge[i].Copy = Gia_ManHashMuxReal( pNew, pFanin->Edge[2].Copy, iLit1, iLit0 );
1542 Str_ObjDelay( pNew, Abc_Lit2Var(pMux->Edge[i].Copy), pFanin->nLutSize, vDelay );
1543 }
1544 return Abc_LitNotCond( pMux->Edge[i].Copy, pMux->Edge[i].fCompl );
1545}
1546void Str_MuxChangeOnce( Str_Mux_t * pTree, int * pPath, int i, int k, Str_Mux_t * pBackup, Gia_Man_t * pNew, Vec_Int_t * vDelay )
1547{
1548 Str_Mux_t * pSpots[3];
1549 int pInds[3], MidFan, MidCom, MidDel, MidCop, c;
1550 int iRes, iCond, fCompl;
1551 // save backup
1552 assert( i + 1 < k );
1553 if ( pBackup )
1554 {
1555 pBackup[0] = pTree[ Abc_Lit2Var(pPath[k]) ];
1556 pBackup[1] = pTree[ Abc_Lit2Var(pPath[i+1])];
1557 pBackup[2] = pTree[ Abc_Lit2Var(pPath[i]) ];
1558 }
1559 // perform changes
1560 pSpots[0] = pTree + Abc_Lit2Var(pPath[k]);
1561 pSpots[1] = pTree + Abc_Lit2Var(pPath[i+1]);
1562 pSpots[2] = pTree + Abc_Lit2Var(pPath[i]);
1563 pInds[0] = Abc_LitIsCompl(pPath[k]);
1564 pInds[1] = Abc_LitIsCompl(pPath[i+1]);
1565 pInds[2] = Abc_LitIsCompl(pPath[i]);
1566 // check
1567 assert( pSpots[0]->Edge[pInds[0]].Fan > 0 );
1568 assert( pSpots[1]->Edge[pInds[1]].Fan > 0 );
1569 // collect complement
1570 fCompl = 0;
1571 for ( c = i+1; c < k; c++ )
1572 fCompl ^= pTree[Abc_Lit2Var(pPath[c])].Edge[Abc_LitIsCompl(pPath[c])].fCompl;
1573 // remember bottom side
1574 MidFan = pSpots[2]->Edge[!pInds[2]].Fan;
1575 MidCom = pSpots[2]->Edge[!pInds[2]].fCompl;
1576 MidDel = pSpots[2]->Edge[!pInds[2]].FanDel;
1577 MidCop = pSpots[2]->Edge[!pInds[2]].Copy;
1578 // update bottom
1579 pSpots[2]->Edge[!pInds[2]].Fan = pSpots[0]->Edge[pInds[0]].Fan;
1580 pSpots[2]->Edge[!pInds[2]].fCompl = 0;
1581 // update top
1582 pSpots[0]->Edge[pInds[0]].Fan = pSpots[2]->Id;
1583 // update middle
1584 pSpots[1]->Edge[pInds[1]].Fan = MidFan;
1585 pSpots[1]->Edge[pInds[1]].fCompl ^= MidCom;
1586 pSpots[1]->Edge[pInds[1]].FanDel = MidDel;
1587 pSpots[1]->Edge[pInds[1]].Copy = MidCop;
1588 // update delay of the control
1589 for ( c = i + 1; c < k; c++ )
1590 pSpots[2]->Edge[2].FanDel = Str_Delay2( pSpots[2]->Edge[2].FanDel, pTree[Abc_Lit2Var(pPath[c])].Edge[2].FanDel, pTree->nLutSize );
1591 if ( pNew == NULL )
1592 return;
1593 // create AND gates
1594 iRes = 1;
1595 for ( c = i; c < k; c++ )
1596 {
1597 assert( pTree[Abc_Lit2Var(pPath[c])].Edge[2].fCompl == 0 );
1598 iCond = pTree[Abc_Lit2Var(pPath[c])].Edge[2].Copy;
1599 iCond = Abc_LitNotCond( iCond, !Abc_LitIsCompl(pPath[c]) );
1600 iRes = Gia_ManHashAnd( pNew, iRes, iCond );
1601 Str_ObjDelay( pNew, Abc_Lit2Var(iRes), pTree->nLutSize, vDelay );
1602 }
1603 // complement the condition
1604 pSpots[2]->Edge[2].Copy = Abc_LitNotCond( iRes, !Abc_LitIsCompl(pPath[i]) );
1605 // complement the path
1606 pSpots[2]->Edge[pInds[2]].fCompl ^= fCompl;
1607}
1608void Str_MuxChangeUndo( Str_Mux_t * pTree, int * pPath, int i, int k, Str_Mux_t * pBackup )
1609{
1610 pTree[ Abc_Lit2Var(pPath[k]) ] = pBackup[0];
1611 pTree[ Abc_Lit2Var(pPath[i+1])] = pBackup[1];
1612 pTree[ Abc_Lit2Var(pPath[i]) ] = pBackup[2];
1613}
1614int Str_MuxFindPathEdge_rec( Str_Mux_t * pMux, int i, int * pPath, int * pnLength )
1615{
1616 extern int Str_MuxFindPath_rec( Str_Mux_t * pMux, int * pPath, int * pnLength );
1617 if ( pMux->Edge[i].Fan > 0 && !Str_MuxFindPath_rec(Str_MuxFanin(pMux, i), pPath, pnLength) )
1618 return 0;
1619 pPath[ (*pnLength)++ ] = Abc_Var2Lit(pMux->Id, i);
1620 return 1;
1621}
1622int Str_MuxFindPath_rec( Str_Mux_t * pMux, int * pPath, int * pnLength )
1623{
1624 int i, DelayMax = Abc_MaxInt( pMux->Edge[0].FanDel, Abc_MaxInt(pMux->Edge[1].FanDel, pMux->Edge[2].FanDel) );
1625 for ( i = 0; i < 2; i++ )
1626 if ( pMux->Edge[i].FanDel == DelayMax )
1627 return Str_MuxFindPathEdge_rec( pMux, i, pPath, pnLength );
1628 if ( pMux->Edge[2].FanDel == DelayMax )
1629 return 0;
1630 assert( 0 );
1631 return -1;
1632}
1633// return node whose both branches are non-trivial
1635{
1636 Str_Mux_t * pMux;
1637 if ( pRoot->Edge[i].Fan <= 0 )
1638 return NULL;
1639 pMux = Str_MuxFanin( pRoot, i );
1640 while ( 1 )
1641 {
1642 if ( pMux->Edge[0].Fan <= 0 && pMux->Edge[1].Fan <= 0 )
1643 return NULL;
1644 if ( pMux->Edge[0].Fan > 0 && pMux->Edge[1].Fan > 0 )
1645 return pMux;
1646 if ( pMux->Edge[0].Fan > 0 )
1647 pMux = Str_MuxFanin( pMux, 0 );
1648 if ( pMux->Edge[1].Fan > 0 )
1649 pMux = Str_MuxFanin( pMux, 1 );
1650 }
1651 assert( 0 );
1652 return NULL;
1653}
1654int Str_MuxTryOnce( Gia_Man_t * pNew, Str_Ntk_t * pNtk, Str_Mux_t * pTree, Str_Mux_t * pRoot, int Edge, Vec_Int_t * vDelay, int fVerbose )
1655{
1656 int pPath[MAX_TREE];
1657 Str_Mux_t pBackup[3];
1658 int Delay, DelayBest = Str_MuxDelayEdge_rec( pRoot, Edge ), DelayInit = DelayBest;
1659 int i, k, nLength = 0, ForkBest = -1, nChecks = 0;
1660 int RetValue = Str_MuxFindPathEdge_rec( pRoot, Edge, pPath, &nLength );
1661 if ( RetValue == 0 )
1662 return 0;
1663 if ( fVerbose )
1664 printf( "Trying node %d with path of length %d.\n", pRoot->Id, nLength );
1665 for ( i = 0; i < nLength; i++ )
1666 for ( k = i+2; k < nLength; k++ )
1667 {
1668 Str_MuxChangeOnce( pTree, pPath, i, k, pBackup, NULL, NULL );
1669 Delay = Str_MuxDelayEdge_rec( pRoot, Edge );
1670 Str_MuxChangeUndo( pTree, pPath, i, k, pBackup );
1671 if ( DelayBest > Delay || (ForkBest > 0 && DelayBest == Delay) )
1672 DelayBest = Delay, ForkBest = (i << 16) | k;
1673 if ( fVerbose )
1674 printf( "%2d %2d -> %3d (%3d)\n", i, k, Delay, DelayBest );
1675 nChecks++;
1676 }
1677 if ( ForkBest == -1 )
1678 {
1679 if ( fVerbose )
1680 printf( "Did not find!\n" );
1681 return 0;
1682 }
1683// Str_MuxDelayPrint_rec( pRoot, Edge ); printf( "\n" );
1684 Str_MuxChangeOnce( pTree, pPath, ForkBest >> 16, ForkBest & 0xFFFF, NULL, pNew, vDelay );
1685// Str_MuxDelayPrint_rec( pRoot, Edge ); printf( "\n" );
1686 if ( fVerbose )
1687 printf( "Node %6d (%3d %3d) : Checks = %d. Delay: %d -> %d.\n",
1688 pRoot->Id, ForkBest >> 16, ForkBest & 0xFFFF, nChecks, DelayInit, DelayBest );
1689 if ( fVerbose )
1690 printf( "\n" );
1691 return 1;
1692}
1693int Str_MuxRestruct_rec( Gia_Man_t * pNew, Str_Ntk_t * pNtk, Str_Mux_t * pTree, Str_Mux_t * pRoot, int Edge, Vec_Int_t * vDelay, int fVerbose )
1694{
1695 int fChanges = 0;
1696 Str_Mux_t * pMux = Str_MuxFindBranching( pRoot, Edge );
1697 if ( pMux != NULL )
1698 fChanges |= Str_MuxRestruct_rec( pNew, pNtk, pTree, pMux, 0, vDelay, fVerbose );
1699 if ( pMux != NULL )
1700 fChanges |= Str_MuxRestruct_rec( pNew, pNtk, pTree, pMux, 1, vDelay, fVerbose );
1701 fChanges |= Str_MuxTryOnce( pNew, pNtk, pTree, pRoot, Edge, vDelay, fVerbose );
1702 return fChanges;
1703}
1704int Str_MuxRestructure2( Gia_Man_t * pNew, Str_Ntk_t * pNtk, int iMux, int nMuxes, Vec_Int_t * vDelay, int nLutSize, int fVerbose )
1705{
1706 int Limit = MAX_TREE;
1707 Str_Mux_t pTree[MAX_TREE];
1708 int Delay, Delay2, fChanges = 0;
1709 if ( nMuxes >= Limit )
1710 return -1;
1711 assert( nMuxes < Limit );
1712 Str_MuxCreate( pTree, pNtk, iMux, nMuxes, vDelay, nLutSize );
1713 Delay = Str_MuxDelayEdge_rec( pTree, 0 );
1714 while ( 1 )
1715 {
1716 if ( !Str_MuxRestruct_rec(pNew, pNtk, pTree, pTree, 0, vDelay, fVerbose) )
1717 break;
1718 fChanges = 1;
1719 }
1720 if ( !fChanges )
1721 return -1;
1722 Delay2 = Str_MuxDelayEdge_rec( pTree, 0 );
1723// printf( "Improved delay for tree %d with %d MUXes (%d -> %d).\n", iMux, nMuxes, Delay, Delay2 );
1724 pNtk->DelayGain += Delay - Delay2;
1725 return Str_MuxToGia_rec( pNew, pTree, 0, vDelay );
1726}
1727int Str_MuxRestructure1( Gia_Man_t * pNew, Str_Ntk_t * pNtk, int iMux, int nMuxes, Vec_Int_t * vDelay, int nLutSize, int fVerbose )
1728{
1729 int Limit = MAX_TREE;
1730 Str_Mux_t pTree[MAX_TREE];
1731 int Delay, Delay2, fChanges = 0;
1732 if ( nMuxes >= Limit )
1733 return -1;
1734 assert( nMuxes < Limit );
1735 Str_MuxCreate( pTree, pNtk, iMux, nMuxes, vDelay, nLutSize );
1736 Delay = Str_MuxDelayEdge_rec( pTree, 0 );
1737 while ( 1 )
1738 {
1739 if ( !Str_MuxTryOnce(pNew, pNtk, pTree, pTree, 0, vDelay, fVerbose) )
1740 break;
1741 fChanges = 1;
1742 }
1743 if ( !fChanges )
1744 return -1;
1745 Delay2 = Str_MuxDelayEdge_rec( pTree, 0 );
1746// printf( "Improved delay for tree %d with %d MUXes (%d -> %d).\n", iMux, nMuxes, Delay, Delay2 );
1747 pNtk->DelayGain += Delay - Delay2;
1748 return Str_MuxToGia_rec( pNew, pTree, 0, vDelay );
1749}
1750int Str_MuxRestructure( Gia_Man_t * pNew, Str_Ntk_t * pNtk, int iMux, int nMuxes, Vec_Int_t * vDelay, int nLutSize, int fRecursive, int fOptArea, int fVerbose )
1751{
1752 extern int Str_MuxRestructureArea( Gia_Man_t * pNew, Str_Ntk_t * pNtk, int iMux, int nMuxes, Vec_Int_t * vDelay, int nLutSize, int fVerbose );
1753 if ( fOptArea )
1754 {
1755 if ( nMuxes < 2 )
1756 return Str_MuxRestructure1( pNew, pNtk, iMux, nMuxes, vDelay, nLutSize, fVerbose );
1757 return Str_MuxRestructureArea( pNew, pNtk, iMux, nMuxes, vDelay, nLutSize, fVerbose );
1758 }
1759 if ( fRecursive )
1760 return Str_MuxRestructure2( pNew, pNtk, iMux, nMuxes, vDelay, nLutSize, fVerbose );
1761 return Str_MuxRestructure1( pNew, pNtk, iMux, nMuxes, vDelay, nLutSize, fVerbose );
1762}
1763
1775int Str_MuxRestructAreaThree( Gia_Man_t * pNew, Str_Mux_t * pMux, Vec_Int_t * vDelay, int fVerbose )
1776{
1777 int iRes;
1778 Str_Mux_t * pFanin0 = Str_MuxFanin( pMux, 0 );
1779 Str_Mux_t * pFanin1 = Str_MuxFanin( pMux, 1 );
1780 assert( pMux->Copy == -1 );
1781 pMux->Copy = -2;
1782 if ( pFanin0->Edge[2].Copy == pFanin1->Edge[2].Copy )
1783 return 0;
1784 iRes = Gia_ManHashMuxReal( pNew, pMux->Edge[2].Copy, pFanin1->Edge[2].Copy, pFanin0->Edge[2].Copy );
1785 Str_ObjDelay( pNew, Abc_Lit2Var(iRes), pMux->nLutSize, vDelay );
1786 pFanin0->Edge[2].Copy = pFanin1->Edge[2].Copy = iRes;
1787// printf( "Created triple\n" );
1788 return 0;
1789}
1790int Str_MuxRestructArea_rec( Gia_Man_t * pNew, Str_Mux_t * pTree, Str_Mux_t * pRoot, int i, Vec_Int_t * vDelay, int fVerbose )
1791{
1792 int Path[4];
1793 int fSkipMoving = 1;
1794 Str_Mux_t * pMux, * pFanin0, * pFanin1;
1795 int nMuxes0, nMuxes1;
1796 if ( pRoot->Edge[i].Fan <= 0 )
1797 return 0;
1798 pMux = Str_MuxFanin( pRoot, i );
1799 nMuxes0 = Str_MuxRestructArea_rec( pNew, pTree, pMux, 0, vDelay, fVerbose );
1800 nMuxes1 = Str_MuxRestructArea_rec( pNew, pTree, pMux, 1, vDelay, fVerbose );
1801 if ( nMuxes0 + nMuxes1 < 2 )
1802 return 1 + nMuxes0 + nMuxes1;
1803 if ( nMuxes0 + nMuxes1 == 2 )
1804 {
1805 if ( nMuxes0 == 2 || nMuxes1 == 2 )
1806 {
1807 pFanin0 = Str_MuxFanin( pMux, (int)(nMuxes1 == 2) );
1808 assert( Str_MuxHasFanin(pFanin0, 0) != Str_MuxHasFanin(pFanin0, 1) );
1809 Path[2] = Abc_Var2Lit(pRoot->Id, i);
1810 Path[1] = Abc_Var2Lit(pMux->Id, (int)(nMuxes1 == 2) );
1811 Path[0] = Abc_Var2Lit(pFanin0->Id, Str_MuxHasFanin(pFanin0, 1));
1812 Str_MuxChangeOnce( pTree, Path, 0, 2, NULL, pNew, vDelay );
1813 }
1814 Str_MuxRestructAreaThree( pNew, Str_MuxFanin(pRoot, i), vDelay, fVerbose );
1815 return 0;
1816 }
1817 assert( nMuxes0 + nMuxes1 == 3 || nMuxes0 + nMuxes1 == 4 );
1818 assert( nMuxes0 == 2 || nMuxes1 == 2 );
1819 if ( fSkipMoving )
1820 {
1821 Str_MuxRestructAreaThree( pNew, pMux, vDelay, fVerbose );
1822 return 0;
1823 }
1824 if ( nMuxes0 == 2 )
1825 {
1826 pFanin0 = Str_MuxFanin( pMux, 0 );
1827 assert( Str_MuxHasFanin(pFanin0, 0) != Str_MuxHasFanin(pFanin0, 1) );
1828 Path[3] = Abc_Var2Lit(pRoot->Id, i);
1829 Path[2] = Abc_Var2Lit(pMux->Id, 0 );
1830 Path[1] = Abc_Var2Lit(pFanin0->Id, Str_MuxHasFanin(pFanin0, 1));
1831 pFanin1 = Str_MuxFanin( pFanin0, Str_MuxHasFanin(pFanin0, 1) );
1832 assert( !Str_MuxHasFanin(pFanin1, 0) && !Str_MuxHasFanin(pFanin1, 1) );
1833 Path[0] = Abc_Var2Lit(pFanin1->Id, 0);
1834 Str_MuxChangeOnce( pTree, Path, 0, 3, NULL, pNew, vDelay );
1835 }
1836 if ( nMuxes1 == 2 )
1837 {
1838 pFanin0 = Str_MuxFanin( pMux, 1 );
1839 assert( Str_MuxHasFanin(pFanin0, 0) != Str_MuxHasFanin(pFanin0, 1) );
1840 Path[3] = Abc_Var2Lit(pRoot->Id, i);
1841 Path[2] = Abc_Var2Lit(pMux->Id, 1 );
1842 Path[1] = Abc_Var2Lit(pFanin0->Id, Str_MuxHasFanin(pFanin0, 1));
1843 pFanin1 = Str_MuxFanin( pFanin0, Str_MuxHasFanin(pFanin0, 1) );
1844 assert( !Str_MuxHasFanin(pFanin1, 0) && !Str_MuxHasFanin(pFanin1, 1) );
1845 Path[0] = Abc_Var2Lit(pFanin1->Id, 0);
1846 Str_MuxChangeOnce( pTree, Path, 0, 3, NULL, pNew, vDelay );
1847 }
1848 Str_MuxRestructAreaThree( pNew, pMux, vDelay, fVerbose );
1849 return nMuxes0 + nMuxes1 - 2;
1850}
1851int Str_MuxRestructureArea( Gia_Man_t * pNew, Str_Ntk_t * pNtk, int iMux, int nMuxes, Vec_Int_t * vDelay, int nLutSize, int fVerbose )
1852{
1853 int Limit = MAX_TREE;
1854 Str_Mux_t pTree[MAX_TREE];
1855 int Result;
1856 if ( nMuxes >= Limit )
1857 return -1;
1858 assert( nMuxes < Limit );
1859 Str_MuxCreate( pTree, pNtk, iMux, nMuxes, vDelay, nLutSize );
1860 Result = Str_MuxRestructArea_rec( pNew, pTree, pTree, 0, vDelay, fVerbose );
1861 assert( Result >= 0 && Result <= 2 );
1862 return Str_MuxToGia_rec( pNew, pTree, 0, vDelay );
1863}
1864
1868
1869
1871
#define ABC_SWAP(Type, a, b)
Definition abc_global.h:253
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#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
struct Vec_Str_t_ Vec_Str_t
Definition bblif.c:46
Cube * p
Definition exorList.c:222
void Gia_ManSuperCollectAnd_rec(Gia_Man_t *p, Gia_Obj_t *pObj, int fStrict)
Definition giaBalAig.c:144
void Gia_ManSimplifyAnd(Vec_Int_t *vSuper)
Definition giaBalAig.c:98
void Gia_ManSuperCollectXor_rec(Gia_Man_t *p, Gia_Obj_t *pObj, int fStrict)
Definition giaBalAig.c:128
void Gia_ManSuperCollect(Gia_Man_t *p, Gia_Obj_t *pObj, int fStrict)
Definition giaBalAig.c:159
void Gia_ManSimplifyXor(Vec_Int_t *vSuper)
FUNCTION DEFINITIONS ///.
Definition giaBalAig.c:78
int Str_MuxFindPathEdge_rec(Str_Mux_t *pMux, int i, int *pPath, int *pnLength)
Definition giaStr.c:1614
#define STR_SUPER
DECLARATIONS ///.
Definition giaStr.c:32
int Str_MuxRestructure(Gia_Man_t *pNew, Str_Ntk_t *pNtk, int iMux, int nMuxes, Vec_Int_t *vDelay, int nLutSize, int fRecursive, int fOptArea, int fVerbose)
Definition giaStr.c:1750
Vec_Int_t * Str_ManCreateRoots(Vec_Wec_t *vGroups, int nObjs)
Definition giaStr.c:420
int Str_MuxRestruct_rec(Gia_Man_t *pNew, Str_Ntk_t *pNtk, Str_Mux_t *pTree, Str_Mux_t *pRoot, int Edge, Vec_Int_t *vDelay, int fVerbose)
Definition giaStr.c:1693
Gia_Man_t * Str_NtkBalance(Gia_Man_t *pGia, Str_Ntk_t *p, int nLutSize, int fUseMuxes, int fRecursive, int fOptArea, int fVerbose)
Definition giaStr.c:1293
Str_Ntk_t * Str_ManNormalize(Gia_Man_t *p)
Definition giaStr.c:755
void Str_MuxStructDump(Gia_Man_t *p, Gia_Obj_t *pObj, Vec_Str_t *vStr)
Definition giaStr.c:346
Gia_Man_t * Gia_ManLutBalance(Gia_Man_t *p, int nLutSize, int fUseMuxes, int fRecursive, int fOptArea, int fVerbose)
Definition giaStr.c:1384
Str_Mux_t * Str_MuxFindBranching(Str_Mux_t *pRoot, int i)
Definition giaStr.c:1634
void Str_MuxDelayPrint_rec(Str_Mux_t *pMux, int i)
Definition giaStr.c:1462
int Str_NtkBalanceTwo(Gia_Man_t *pNew, Str_Ntk_t *p, Str_Obj_t *pObj, int i, int j, Vec_Int_t *vDelay, int *pCost, int *pSuper, word *pMatrix, int nSize, int nLutSize, int CostBest)
Definition giaStr.c:1057
int Str_ManVectorAffinity(Gia_Man_t *p, Vec_Int_t *vSuper, Vec_Int_t *vDelay, word *Matrix, int nLimit)
Definition giaStr.c:862
@ STR_BUF
Definition giaStr.c:42
@ STR_NONE
Definition giaStr.c:36
@ STR_MUX
Definition giaStr.c:41
@ STR_PO
Definition giaStr.c:43
@ STR_UNUSED
Definition giaStr.c:44
@ STR_XOR
Definition giaStr.c:40
@ STR_PI
Definition giaStr.c:38
@ STR_AND
Definition giaStr.c:39
@ STR_CONST0
Definition giaStr.c:37
int Str_MuxRestructure2(Gia_Man_t *pNew, Str_Ntk_t *pNtk, int iMux, int nMuxes, Vec_Int_t *vDelay, int nLutSize, int fVerbose)
Definition giaStr.c:1704
void Str_MuxCreate(Str_Mux_t *pTree, Str_Ntk_t *pNtk, int iMux, int nMuxes, Vec_Int_t *vDelay, int nLutSize)
Definition giaStr.c:1500
int Str_MuxRestructureArea(Gia_Man_t *pNew, Str_Ntk_t *pNtk, int iMux, int nMuxes, Vec_Int_t *vDelay, int nLutSize, int fVerbose)
Definition giaStr.c:1851
Gia_Man_t * Gia_ManDupMuxesNoHash(Gia_Man_t *p)
Definition giaStr.c:225
Gia_Man_t * Str_NtkToGia(Gia_Man_t *pGia, Str_Ntk_t *p)
Definition giaStr.c:172
void Str_MuxChangeOnce(Str_Mux_t *pTree, int *pPath, int i, int k, Str_Mux_t *pBackup, Gia_Man_t *pNew, Vec_Int_t *vDelay)
Definition giaStr.c:1546
struct Str_Ntk_t_ Str_Ntk_t
Definition giaStr.c:56
struct Str_Obj_t_ Str_Obj_t
Definition giaStr.c:47
Vec_Wec_t * Str_ManDeriveTrees(Gia_Man_t *p)
Definition giaStr.c:362
void Str_MuxInputsCollect_rec(Gia_Man_t *p, Gia_Obj_t *pObj, Vec_Int_t *vNodes)
Definition giaStr.c:298
#define MAX_TREE
Definition giaStr.c:33
int Str_MuxRestructAreaThree(Gia_Man_t *pNew, Str_Mux_t *pMux, Vec_Int_t *vDelay, int fVerbose)
Definition giaStr.c:1775
Str_Ntk_t * Str_ManNormalizeInt(Gia_Man_t *p, Vec_Wec_t *vGroups, Vec_Int_t *vRoots)
Definition giaStr.c:728
struct Str_Mux_t_ Str_Mux_t
Definition giaStr.c:1449
int Str_MuxFindPath_rec(Str_Mux_t *pMux, int *pPath, int *pnLength)
Definition giaStr.c:1622
int Str_MuxToGia_rec(Gia_Man_t *pNew, Str_Mux_t *pMux, int i, Vec_Int_t *vDelay)
Definition giaStr.c:1532
int Str_MuxRestructure1(Gia_Man_t *pNew, Str_Ntk_t *pNtk, int iMux, int nMuxes, Vec_Int_t *vDelay, int nLutSize, int fVerbose)
Definition giaStr.c:1727
int Str_MuxRestructArea_rec(Gia_Man_t *pNew, Str_Mux_t *pTree, Str_Mux_t *pRoot, int i, Vec_Int_t *vDelay, int fVerbose)
Definition giaStr.c:1790
struct Str_Man_t_ Str_Man_t
Definition giaStr.c:68
void Str_NtkBalanceMulti2(Gia_Man_t *pNew, Str_Ntk_t *p, Str_Obj_t *pObj, Vec_Int_t *vDelay, int nLutSize)
Definition giaStr.c:1043
void Str_MuxTraverse_rec(Gia_Man_t *p, int i)
Definition giaStr.c:432
int Str_ManMuxCountOne(char *p)
Definition giaStr.c:355
int Str_MuxDelayEdge_rec(Str_Mux_t *pMux, int i)
Definition giaStr.c:1489
void Str_NtkBalanceMulti(Gia_Man_t *pNew, Str_Ntk_t *p, Str_Obj_t *pObj, Vec_Int_t *vDelay, int nLutSize)
Definition giaStr.c:1093
void Str_MuxInputsCollect(Gia_Man_t *p, Gia_Obj_t *pObj, Vec_Int_t *vNodes)
Definition giaStr.c:309
void Str_MuxChangeUndo(Str_Mux_t *pTree, int *pPath, int i, int k, Str_Mux_t *pBackup)
Definition giaStr.c:1608
void Str_MuxStructDump_rec(Gia_Man_t *p, Gia_Obj_t *pObj, Vec_Str_t *vStr)
Definition giaStr.c:333
void Str_MuxStructCollect(Gia_Man_t *p, Gia_Obj_t *pObj, Vec_Int_t *vNodes)
Definition giaStr.c:325
int Str_MuxTryOnce(Gia_Man_t *pNew, Str_Ntk_t *pNtk, Str_Mux_t *pTree, Str_Mux_t *pRoot, int Edge, Vec_Int_t *vDelay, int fVerbose)
Definition giaStr.c:1654
void Str_NtkBalanceMux(Gia_Man_t *pNew, Str_Ntk_t *p, Str_Obj_t *pObj, Vec_Int_t *vDelay, int nLutSize, int nGroups, int nMuxes, int fRecursive, int fOptArea, int fVerbose)
Definition giaStr.c:1259
#define Str_NtkManForEachObj(p, pObj)
Definition giaStr.c:89
void Str_ManCheckOverlap(Gia_Man_t *p, Vec_Wec_t *vGroups)
Definition giaStr.c:446
void Str_ManNormalize_rec(Str_Ntk_t *pNtk, Gia_Man_t *p, Gia_Obj_t *pObj, Vec_Wec_t *vGroups, Vec_Int_t *vRoots)
Definition giaStr.c:639
struct Str_Edg_t_ Str_Edg_t
Definition giaStr.c:1440
void Str_MuxStructCollect_rec(Gia_Man_t *p, Gia_Obj_t *pObj, Vec_Int_t *vNodes)
Definition giaStr.c:317
void Gia_ManStop(Gia_Man_t *p)
Definition giaMan.c:82
Gia_Man_t * Gia_ManDupMuxes(Gia_Man_t *p, int Limit)
Definition giaMuxes.c:98
void Gia_ManHashStart(Gia_Man_t *p)
Definition giaHash.c:125
int Gia_ManHasDangling(Gia_Man_t *p)
Definition giaUtil.c:1353
Gia_Obj_t * Gia_ObjRecognizeMux(Gia_Obj_t *pNode, Gia_Obj_t **ppNodeT, Gia_Obj_t **ppNodeE)
Definition giaUtil.c:1056
int Gia_ManIsNormalized(Gia_Man_t *p)
Definition giaTim.c:114
#define Gia_ManForEachAnd(p, pObj, i)
Definition gia.h:1214
int Gia_ManHashMuxReal(Gia_Man_t *p, int iLitC, int iLit1, int iLit0)
Definition giaHash.c:521
void Gia_ManSetRegNum(Gia_Man_t *p, int nRegs)
Definition giaMan.c:764
Gia_Man_t * Gia_ManStart(int nObjsMax)
FUNCTION DEFINITIONS ///.
Definition giaMan.c:57
struct Gia_Obj_t_ Gia_Obj_t
Definition gia.h:76
Gia_Man_t * Gia_ManDupNoMuxes(Gia_Man_t *p, int fSkipBufs)
Definition giaMuxes.c:228
int Gia_ManHashXor(Gia_Man_t *p, int iLit0, int iLit1)
Definition giaHash.c:668
int Gia_ObjIsMuxType(Gia_Obj_t *pNode)
Definition giaUtil.c:982
void Gia_ManFillValue(Gia_Man_t *p)
Definition giaUtil.c:369
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
#define Gia_ManForEachObj1(p, pObj, i)
Definition gia.h:1192
#define Gia_ManForEachObjVec(vVec, p, pObj, i)
Definition gia.h:1194
int Gia_ManHashMux(Gia_Man_t *p, int iCtrl, int iData1, int iData0)
Definition giaHash.c:692
Gia_Man_t * Gia_ManCleanup(Gia_Man_t *p)
Definition giaScl.c:84
void Gia_ManCleanMark0(Gia_Man_t *p)
Definition giaUtil.c:256
void Gia_ManTransferTiming(Gia_Man_t *p, Gia_Man_t *pGia)
Definition giaIf.c:2370
int Gia_ObjRecognizeExor(Gia_Obj_t *pObj, Gia_Obj_t **ppFan0, Gia_Obj_t **ppFan1)
Definition giaUtil.c:1018
void Gia_ManCreateRefs(Gia_Man_t *p)
Definition giaUtil.c:779
Gia_Man_t * Gia_ManDupNormalize(Gia_Man_t *p, int fHashMapping)
Definition giaTim.c:139
int Gia_ManHashAnd(Gia_Man_t *p, int iLit0, int iLit1)
Definition giaHash.c:576
void Gia_ManIncrementTravId(Gia_Man_t *p)
Definition giaUtil.c:190
#define Gia_ManForEachMuxId(p, i)
Definition gia.h:1218
int Gia_ManHashXorReal(Gia_Man_t *p, int iLit0, int iLit1)
Definition giaHash.c:469
#define Gia_ManForEachCo(p, pObj, i)
Definition gia.h:1236
#define Gia_ManForEachCi(p, pObj, i)
Definition gia.h:1228
void Gia_ManHashStop(Gia_Man_t *p)
Definition giaHash.c:149
Gia_Man_t * Gia_ManDupUnnormalize(Gia_Man_t *p)
Definition giaTim.c:382
unsigned __int64 word
DECLARATIONS ///.
Definition kitPerm.c:36
Vec_Int_t * vSuper
Definition gia.h:234
unsigned * pMuxes
Definition gia.h:106
char * pSpec
Definition gia.h:100
int nObjsAlloc
Definition gia.h:104
void * pManTime
Definition gia.h:194
char * pName
Definition gia.h:99
Vec_Int_t vCopies
Definition gia.h:152
Vec_Int_t * vStore
Definition gia.h:235
unsigned Value
Definition gia.h:89
unsigned fMark0
Definition gia.h:81
int FanDel
Definition giaStr.c:1445
int fCompl
Definition giaStr.c:1444
int nLutSize
Definition giaStr.c:73
int fCutMin
Definition giaStr.c:74
Gia_Man_t * pOld
Definition giaStr.c:72
Gia_Man_t * pNew
Definition giaStr.c:78
Vec_Int_t * vDelays
Definition giaStr.c:79
Str_Ntk_t * pNtk
Definition giaStr.c:76
Str_Edg_t Edge[3]
Definition giaStr.c:1456
int Delay
Definition giaStr.c:1453
int nLutSize
Definition giaStr.c:1455
int nObjsAlloc
Definition giaStr.c:60
Vec_Int_t vFanins
Definition giaStr.c:62
int nGroups
Definition giaStr.c:65
Str_Obj_t * pObjs
Definition giaStr.c:61
int nObjCount[STR_UNUSED]
Definition giaStr.c:63
int DelayGain
Definition giaStr.c:66
int nObjs
Definition giaStr.c:59
int nTrees
Definition giaStr.c:64
unsigned Type
Definition giaStr.c:50
unsigned nFanins
Definition giaStr.c:51
int iTop
Definition giaStr.c:53
int iOffset
Definition giaStr.c:52
int iCopy
Definition giaStr.c:54
void Tim_ManSetCoArrival(Tim_Man_t *p, int iCo, float Delay)
Definition timTime.c:116
int Tim_ManBoxNum(Tim_Man_t *p)
Definition timMan.c:722
void Tim_ManInitPiArrivalAll(Tim_Man_t *p, float Delay)
Definition timTime.c:78
typedefABC_NAMESPACE_HEADER_START struct Tim_Man_t_ Tim_Man_t
INCLUDES ///.
Definition tim.h:92
void Tim_ManIncrementTravId(Tim_Man_t *p)
DECLARATIONS ///.
Definition timTrav.c:44
void Tim_ManStop(Tim_Man_t *p)
Definition timMan.c:378
Tim_Man_t * Tim_ManDup(Tim_Man_t *p, int fUnitDelay)
Definition timMan.c:86
float Tim_ManGetCiArrival(Tim_Man_t *p, int iCi)
Definition timTime.c:174
void Abc_NamStop(Abc_Nam_t *p)
Definition utilNam.c:112
int Abc_NamStrFindOrAdd(Abc_Nam_t *p, char *pStr, int *pfFound)
Definition utilNam.c:453
int Abc_NamObjNumMax(Abc_Nam_t *p)
Definition utilNam.c:231
Abc_Nam_t * Abc_NamStart(int nObjs, int nAveSize)
FUNCTION DEFINITIONS ///.
Definition utilNam.c:80
#define Abc_NamManForEachObj(p, pStr, i)
MACRO DEFINITIONS ///.
Definition utilNam.h:45
typedefABC_NAMESPACE_HEADER_START struct Abc_Nam_t_ Abc_Nam_t
INCLUDES ///.
Definition utilNam.h:39
#define assert(ex)
Definition util_old.h:213
char * memset()
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
#define Vec_IntForEachEntryStartStop(vVec, Entry, i, Start, Stop)
Definition vecInt.h:60
#define Vec_IntForEachEntryStart(vVec, Entry, i, Start)
Definition vecInt.h:56
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
Definition vecWec.h:55
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
Definition vecWec.h:42