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