abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
resFilter.c
Go to the documentation of this file.
1 /**CFile****************************************************************
2 
3  FileName [resFilter.c]
4 
5  SystemName [ABC: Logic synthesis and verification system.]
6 
7  PackageName [Resynthesis package.]
8 
9  Synopsis [Filtering resubstitution candidates.]
10 
11  Author [Alan Mishchenko]
12 
13  Affiliation [UC Berkeley]
14 
15  Date [Ver. 1.0. Started - January 15, 2007.]
16 
17  Revision [$Id: resFilter.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "base/abc/abc.h"
22 #include "resInt.h"
23 
25 
26 
27 ////////////////////////////////////////////////////////////////////////
28 /// DECLARATIONS ///
29 ////////////////////////////////////////////////////////////////////////
30 
31 static unsigned * Res_FilterCollectFaninInfo( Res_Win_t * pWin, Res_Sim_t * pSim, unsigned uMask );
32 static int Res_FilterCriticalFanin( Abc_Obj_t * pNode );
33 
34 ////////////////////////////////////////////////////////////////////////
35 /// FUNCTION DEFINITIONS ///
36 ////////////////////////////////////////////////////////////////////////
37 
38 /**Function*************************************************************
39 
40  Synopsis [Finds sets of feasible candidates.]
41 
42  Description []
43 
44  SideEffects []
45 
46  SeeAlso []
47 
48 ***********************************************************************/
49 int Res_FilterCandidates( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW, int nFaninsMax, int fArea )
50 {
51  Abc_Obj_t * pFanin, * pFanin2, * pFaninTemp;
52  unsigned * pInfo, * pInfoDiv, * pInfoDiv2;
53  int Counter, RetValue, i, i2, d, d2, iDiv, iDiv2, k;
54 
55  // check that the info the node is one
56  pInfo = (unsigned *)Vec_PtrEntry( pSim->vOuts, 1 );
57  RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut );
58  if ( RetValue == 0 )
59  {
60 // printf( "Failed 1!\n" );
61  return 0;
62  }
63 
64  // collect the fanin info
65  pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~0 );
66  RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut );
67  if ( RetValue == 0 )
68  {
69 // printf( "Failed 2!\n" );
70  return 0;
71  }
72 
73  // try removing each fanin
74 // printf( "Fanins: " );
75  Counter = 0;
76  Vec_VecClear( vResubs );
77  Vec_VecClear( vResubsW );
78  Abc_ObjForEachFanin( pWin->pNode, pFanin, i )
79  {
80  if ( fArea && Abc_ObjFanoutNum(pFanin) > 1 )
81  continue;
82  // get simulation info without this fanin
83  pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << i) );
84  RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut );
85  if ( RetValue )
86  {
87 // printf( "Node %4d. Candidate fanin %4d.\n", pWin->pNode->Id, pFanin->Id );
88  // collect the nodes
89  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) );
90  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) );
91  Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k )
92  {
93  if ( k != i )
94  {
95  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) );
96  Vec_VecPush( vResubsW, Counter, pFaninTemp );
97  }
98  }
99  Counter++;
100  if ( Counter == Vec_VecSize(vResubs) )
101  return Counter;
102  }
103  }
104 
105  // try replacing each critical fanin by a non-critical fanin
106  Abc_ObjForEachFanin( pWin->pNode, pFanin, i )
107  {
108  if ( Abc_ObjFanoutNum(pFanin) > 1 )
109  continue;
110  // get simulation info without this fanin
111  pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << i) );
112  // go over the set of divisors
113  for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ )
114  {
115  pInfoDiv = (unsigned *)Vec_PtrEntry( pSim->vOuts, d );
116  iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2);
117  if ( !Abc_InfoIsOrOne( pInfo, pInfoDiv, pSim->nWordsOut ) )
118  continue;
119  // collect the nodes
120  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) );
121  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) );
122  // collect the remaning fanins and the divisor
123  Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k )
124  {
125  if ( k != i )
126  {
127  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) );
128  Vec_VecPush( vResubsW, Counter, pFaninTemp );
129  }
130  }
131  // collect the divisor
132  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) );
133  Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) );
134  Counter++;
135  if ( Counter == Vec_VecSize(vResubs) )
136  return Counter;
137  }
138  }
139 
140  // consider the case when two fanins can be added instead of one
141  if ( Abc_ObjFaninNum(pWin->pNode) < nFaninsMax )
142  {
143  // try to replace each critical fanin by two non-critical fanins
144  Abc_ObjForEachFanin( pWin->pNode, pFanin, i )
145  {
146  if ( Abc_ObjFanoutNum(pFanin) > 1 )
147  continue;
148  // get simulation info without this fanin
149  pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << i) );
150  // go over the set of divisors
151  for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ )
152  {
153  pInfoDiv = (unsigned *)Vec_PtrEntry( pSim->vOuts, d );
154  iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2);
155  // go through the second divisor
156  for ( d2 = d + 1; d2 < Abc_NtkPoNum(pAig); d2++ )
157  {
158  pInfoDiv2 = (unsigned *)Vec_PtrEntry( pSim->vOuts, d2 );
159  iDiv2 = d2 - (Abc_ObjFaninNum(pWin->pNode) + 2);
160  if ( !Abc_InfoIsOrOne3( pInfo, pInfoDiv, pInfoDiv2, pSim->nWordsOut ) )
161  continue;
162  // collect the nodes
163  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) );
164  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) );
165  // collect the remaning fanins and the divisor
166  Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k )
167  {
168  if ( k != i )
169  {
170  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) );
171  Vec_VecPush( vResubsW, Counter, pFaninTemp );
172  }
173  }
174  // collect the divisor
175  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) );
176  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d2) );
177  Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) );
178  Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv2) );
179  Counter++;
180  if ( Counter == Vec_VecSize(vResubs) )
181  return Counter;
182  }
183  }
184  }
185  }
186 
187  // try to replace two nets by one
188  if ( !fArea )
189  {
190  Abc_ObjForEachFanin( pWin->pNode, pFanin, i )
191  {
192  for ( i2 = i + 1; i2 < Abc_ObjFaninNum(pWin->pNode); i2++ )
193  {
194  pFanin2 = Abc_ObjFanin(pWin->pNode, i2);
195  // get simulation info without these fanins
196  pInfo = Res_FilterCollectFaninInfo( pWin, pSim, (~(1 << i)) & (~(1 << i2)) );
197  // go over the set of divisors
198  for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ )
199  {
200  pInfoDiv = (unsigned *)Vec_PtrEntry( pSim->vOuts, d );
201  iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2);
202  if ( !Abc_InfoIsOrOne( pInfo, pInfoDiv, pSim->nWordsOut ) )
203  continue;
204  // collect the nodes
205  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) );
206  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) );
207  // collect the remaning fanins and the divisor
208  Abc_ObjForEachFanin( pWin->pNode, pFaninTemp, k )
209  {
210  if ( k != i && k != i2 )
211  {
212  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) );
213  Vec_VecPush( vResubsW, Counter, pFaninTemp );
214  }
215  }
216  // collect the divisor
217  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) );
218  Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) );
219  Counter++;
220  if ( Counter == Vec_VecSize(vResubs) )
221  return Counter;
222  }
223  }
224  }
225  }
226  return Counter;
227 }
228 
229 
230 /**Function*************************************************************
231 
232  Synopsis [Finds sets of feasible candidates.]
233 
234  Description [This procedure is a special case of the above.]
235 
236  SideEffects []
237 
238  SeeAlso []
239 
240 ***********************************************************************/
241 int Res_FilterCandidatesArea( Res_Win_t * pWin, Abc_Ntk_t * pAig, Res_Sim_t * pSim, Vec_Vec_t * vResubs, Vec_Vec_t * vResubsW, int nFaninsMax )
242 {
243  Abc_Obj_t * pFanin;
244  unsigned * pInfo, * pInfoDiv, * pInfoDiv2;
245  int Counter, RetValue, d, d2, k, iDiv, iDiv2, iBest;
246 
247  // check that the info the node is one
248  pInfo = (unsigned *)Vec_PtrEntry( pSim->vOuts, 1 );
249  RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut );
250  if ( RetValue == 0 )
251  {
252 // printf( "Failed 1!\n" );
253  return 0;
254  }
255 
256  // collect the fanin info
257  pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~0 );
258  RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut );
259  if ( RetValue == 0 )
260  {
261 // printf( "Failed 2!\n" );
262  return 0;
263  }
264 
265  // try removing fanins
266 // printf( "Fanins: " );
267  Counter = 0;
268  Vec_VecClear( vResubs );
269  Vec_VecClear( vResubsW );
270  // get the best fanins
271  iBest = Res_FilterCriticalFanin( pWin->pNode );
272  if ( iBest == -1 )
273  return 0;
274 
275  // get the info without the critical fanin
276  pInfo = Res_FilterCollectFaninInfo( pWin, pSim, ~(1 << iBest) );
277  RetValue = Abc_InfoIsOne( pInfo, pSim->nWordsOut );
278  if ( RetValue )
279  {
280 // printf( "Can be done without one!\n" );
281  // collect the nodes
282  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) );
283  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) );
284  Abc_ObjForEachFanin( pWin->pNode, pFanin, k )
285  {
286  if ( k != iBest )
287  {
288  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) );
289  Vec_VecPush( vResubsW, Counter, pFanin );
290  }
291  }
292  Counter++;
293 // printf( "*" );
294  return Counter;
295  }
296 
297  // go through the divisors
298  for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ )
299  {
300  pInfoDiv = (unsigned *)Vec_PtrEntry( pSim->vOuts, d );
301  iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2);
302  if ( !Abc_InfoIsOrOne( pInfo, pInfoDiv, pSim->nWordsOut ) )
303  continue;
304 //if ( Abc_ObjLevel(pWin->pNode) <= Abc_ObjLevel( Vec_PtrEntry(pWin->vDivs, iDiv) ) )
305 // printf( "Node level = %d. Divisor level = %d.\n", Abc_ObjLevel(pWin->pNode), Abc_ObjLevel( Vec_PtrEntry(pWin->vDivs, iDiv) ) );
306  // collect the nodes
307  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) );
308  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) );
309  // collect the remaning fanins and the divisor
310  Abc_ObjForEachFanin( pWin->pNode, pFanin, k )
311  {
312  if ( k != iBest )
313  {
314  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) );
315  Vec_VecPush( vResubsW, Counter, pFanin );
316  }
317  }
318  // collect the divisor
319  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) );
320  Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) );
321  Counter++;
322 
323  if ( Counter == Vec_VecSize(vResubs) )
324  break;
325  }
326 
327  if ( Counter > 0 || Abc_ObjFaninNum(pWin->pNode) >= nFaninsMax )
328  return Counter;
329 
330  // try to find the node pairs
331  for ( d = Abc_ObjFaninNum(pWin->pNode) + 2; d < Abc_NtkPoNum(pAig); d++ )
332  {
333  pInfoDiv = (unsigned *)Vec_PtrEntry( pSim->vOuts, d );
334  iDiv = d - (Abc_ObjFaninNum(pWin->pNode) + 2);
335  // go through the second divisor
336  for ( d2 = d + 1; d2 < Abc_NtkPoNum(pAig); d2++ )
337  {
338  pInfoDiv2 = (unsigned *)Vec_PtrEntry( pSim->vOuts, d2 );
339  iDiv2 = d2 - (Abc_ObjFaninNum(pWin->pNode) + 2);
340 
341  if ( !Abc_InfoIsOrOne3( pInfo, pInfoDiv, pInfoDiv2, pSim->nWordsOut ) )
342  continue;
343  // collect the nodes
344  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,0) );
345  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,1) );
346  // collect the remaning fanins and the divisor
347  Abc_ObjForEachFanin( pWin->pNode, pFanin, k )
348  {
349  if ( k != iBest )
350  {
351  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,2+k) );
352  Vec_VecPush( vResubsW, Counter, pFanin );
353  }
354  }
355  // collect the divisor
356  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d) );
357  Vec_VecPush( vResubs, Counter, Abc_NtkPo(pAig,d2) );
358  Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv) );
359  Vec_VecPush( vResubsW, Counter, Vec_PtrEntry(pWin->vDivs, iDiv2) );
360  Counter++;
361 
362  if ( Counter == Vec_VecSize(vResubs) )
363  break;
364  }
365  if ( Counter == Vec_VecSize(vResubs) )
366  break;
367  }
368  return Counter;
369 }
370 
371 
372 /**Function*************************************************************
373 
374  Synopsis [Finds sets of feasible candidates.]
375 
376  Description []
377 
378  SideEffects []
379 
380  SeeAlso []
381 
382 ***********************************************************************/
383 unsigned * Res_FilterCollectFaninInfo( Res_Win_t * pWin, Res_Sim_t * pSim, unsigned uMask )
384 {
385  Abc_Obj_t * pFanin;
386  unsigned * pInfo;
387  int i;
388  pInfo = (unsigned *)Vec_PtrEntry( pSim->vOuts, 0 );
389  Abc_InfoClear( pInfo, pSim->nWordsOut );
390  Abc_ObjForEachFanin( pWin->pNode, pFanin, i )
391  {
392  if ( uMask & (1 << i) )
393  Abc_InfoOr( pInfo, (unsigned *)Vec_PtrEntry(pSim->vOuts, 2+i), pSim->nWordsOut );
394  }
395  return pInfo;
396 }
397 
398 
399 /**Function*************************************************************
400 
401  Synopsis [Returns the index of the most critical fanin.]
402 
403  Description []
404 
405  SideEffects []
406 
407  SeeAlso []
408 
409 ***********************************************************************/
411 {
412  Abc_Obj_t * pFanin;
413  int i, iBest = -1, CostMax = 0, CostCur;
414  Abc_ObjForEachFanin( pNode, pFanin, i )
415  {
416  if ( !Abc_ObjIsNode(pFanin) )
417  continue;
418  if ( Abc_ObjFanoutNum(pFanin) > 1 )
419  continue;
420  CostCur = Res_WinVisitMffc( pFanin );
421  if ( CostMax < CostCur )
422  {
423  CostMax = CostCur;
424  iBest = i;
425  }
426  }
427 // if ( CostMax > 0 )
428 // printf( "<%d>", CostMax );
429  return iBest;
430 }
431 
432 
433 ////////////////////////////////////////////////////////////////////////
434 /// END OF FILE ///
435 ////////////////////////////////////////////////////////////////////////
436 
437 
439 
static int Res_FilterCriticalFanin(Abc_Obj_t *pNode)
Definition: resFilter.c:410
int nWordsOut
Definition: resInt.h:82
static void Vec_VecPush(Vec_Vec_t *p, int Level, void *Entry)
Definition: vecVec.h:456
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition: vecVec.h:42
int Res_FilterCandidatesArea(Res_Win_t *pWin, Abc_Ntk_t *pAig, Res_Sim_t *pSim, Vec_Vec_t *vResubs, Vec_Vec_t *vResubsW, int nFaninsMax)
Definition: resFilter.c:241
static int Abc_ObjFanoutNum(Abc_Obj_t *pObj)
Definition: abc.h:365
static int Abc_ObjFaninNum(Abc_Obj_t *pObj)
Definition: abc.h:364
typedefABC_NAMESPACE_HEADER_START struct Res_Win_t_ Res_Win_t
INCLUDES ///.
Definition: resInt.h:44
static ABC_NAMESPACE_IMPL_START unsigned * Res_FilterCollectFaninInfo(Res_Win_t *pWin, Res_Sim_t *pSim, unsigned uMask)
DECLARATIONS ///.
Definition: resFilter.c:383
static void Vec_VecClear(Vec_Vec_t *p)
Definition: vecVec.h:437
static int Abc_ObjIsNode(Abc_Obj_t *pObj)
Definition: abc.h:355
#define ABC_NAMESPACE_IMPL_END
Definition: abc_global.h:108
static int Counter
static void Abc_InfoClear(unsigned *p, int nWords)
Definition: abc.h:236
static void Abc_InfoOr(unsigned *p, unsigned *q, int nWords)
Definition: abc.h:243
#define ABC_NAMESPACE_IMPL_START
Definition: abc_global.h:107
static void * Vec_PtrEntry(Vec_Ptr_t *p, int i)
Definition: vecPtr.h:362
static Abc_Obj_t * Abc_NtkPo(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:316
static int Abc_NtkPoNum(Abc_Ntk_t *pNtk)
Definition: abc.h:286
#define Abc_ObjForEachFanin(pObj, pFanin, i)
Definition: abc.h:524
int Res_FilterCandidates(Res_Win_t *pWin, Abc_Ntk_t *pAig, Res_Sim_t *pSim, Vec_Vec_t *vResubs, Vec_Vec_t *vResubsW, int nFaninsMax, int fArea)
FUNCTION DEFINITIONS ///.
Definition: resFilter.c:49
static int Vec_VecSize(Vec_Vec_t *p)
Definition: vecVec.h:222
Vec_Ptr_t * vOuts
Definition: resInt.h:88
static int Abc_InfoIsOne(unsigned *p, int nWords)
Definition: abc.h:240
static int Abc_InfoIsOrOne(unsigned *p, unsigned *q, int nWords)
Definition: abc.h:245
int Res_WinVisitMffc(Abc_Obj_t *pNode)
Definition: resDivs.c:272
static Abc_Obj_t * Abc_ObjFanin(Abc_Obj_t *pObj, int i)
Definition: abc.h:372
static int Abc_InfoIsOrOne3(unsigned *p, unsigned *q, unsigned *r, int nWords)
Definition: abc.h:246