ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
sfmWin.c
Go to the documentation of this file.
1
20
21#include "sfmInt.h"
22
24
25
29
33
45int Sfm_ObjRef_rec( Sfm_Ntk_t * p, int iObj )
46{
47 int i, iFanin, Value, Count;
48 if ( Sfm_ObjIsPi(p, iObj) )
49 return 0;
50 assert( Sfm_ObjIsNode(p, iObj) );
51 Value = Sfm_ObjRefIncrement(p, iObj);
52 if ( Value > 1 )
53 return 0;
54 assert( Value == 1 );
55 Count = 1;
56 Sfm_ObjForEachFanin( p, iObj, iFanin, i )
57 Count += Sfm_ObjRef_rec( p, iFanin );
58 return Count;
59}
60int Sfm_ObjRef( Sfm_Ntk_t * p, int iObj )
61{
62 int i, iFanin, Count = 1;
63 Sfm_ObjForEachFanin( p, iObj, iFanin, i )
64 Count += Sfm_ObjRef_rec( p, iFanin );
65 return Count;
66}
67int Sfm_ObjDeref_rec( Sfm_Ntk_t * p, int iObj )
68{
69 int i, iFanin, Value, Count;
70 if ( Sfm_ObjIsPi(p, iObj) )
71 return 0;
72 assert( Sfm_ObjIsNode(p, iObj) );
73 Value = Sfm_ObjRefDecrement(p, iObj);
74 if ( Value > 0 )
75 return 0;
76 assert( Value == 0 );
77 Count = 1;
78 Sfm_ObjForEachFanin( p, iObj, iFanin, i )
79 Count += Sfm_ObjDeref_rec( p, iFanin );
80 return Count;
81}
82int Sfm_ObjDeref( Sfm_Ntk_t * p, int iObj )
83{
84 int i, iFanin, Count = 1;
85 Sfm_ObjForEachFanin( p, iObj, iFanin, i )
86 Count += Sfm_ObjDeref_rec( p, iFanin );
87 return Count;
88}
89int Sfm_ObjMffcSize( Sfm_Ntk_t * p, int iObj )
90{
91 int Count1, Count2;
92 if ( Sfm_ObjIsPi(p, iObj) )
93 return 0;
94 if ( Sfm_ObjFanoutNum(p, iObj) != 1 )
95 return 0;
96 assert( Sfm_ObjIsNode( p, iObj ) );
97 Count1 = Sfm_ObjDeref( p, iObj );
98 Count2 = Sfm_ObjRef( p, iObj );
99 assert( Count1 == Count2 );
100 return Count1;
101}
102
114static inline void Sfm_NtkIncrementTravId( Sfm_Ntk_t * p ) { p->nTravIds++; }
115static inline void Sfm_ObjSetTravIdCurrent( Sfm_Ntk_t * p, int Id ) { Vec_IntWriteEntry( &p->vTravIds, Id, p->nTravIds ); }
116static inline int Sfm_ObjIsTravIdCurrent( Sfm_Ntk_t * p, int Id ) { return (Vec_IntEntry(&p->vTravIds, Id) == p->nTravIds); }
117static inline int Sfm_ObjIsTravIdPrevious( Sfm_Ntk_t * p, int Id ) { return (Vec_IntEntry(&p->vTravIds, Id) == p->nTravIds-1); }
118
119static inline void Sfm_NtkIncrementTravId2( Sfm_Ntk_t * p ) { p->nTravIds2++; }
120static inline void Sfm_ObjSetTravIdCurrent2( Sfm_Ntk_t * p, int Id ) { Vec_IntWriteEntry( &p->vTravIds2, Id, p->nTravIds2 ); }
121static inline int Sfm_ObjIsTravIdCurrent2( Sfm_Ntk_t * p, int Id ) { return (Vec_IntEntry(&p->vTravIds2, Id) == p->nTravIds2); }
122
123
136void Sfm_NtkDfs_rec( Sfm_Ntk_t * p, int iNode, Vec_Int_t * vNodes, Vec_Wec_t * vGroups, Vec_Int_t * vGroupMap, Vec_Int_t * vBoxesLeft )
137{
138 int i, iFanin;
139 if ( Sfm_ObjIsPi(p, iNode) )
140 return;
141 if ( Sfm_ObjIsTravIdCurrent(p, iNode) )
142 return;
143 if ( Vec_IntEntry(vGroupMap, iNode) >= 0 )
144 {
145 int k, iGroup = Abc_Lit2Var( Vec_IntEntry(vGroupMap, iNode) );
146 Vec_Int_t * vGroup = Vec_WecEntry( vGroups, iGroup );
147 Vec_IntForEachEntry( vGroup, iNode, i )
148 assert( Sfm_ObjIsNode(p, iNode) );
149 Vec_IntForEachEntry( vGroup, iNode, i )
150 Sfm_ObjSetTravIdCurrent( p, iNode );
151 Vec_IntForEachEntry( vGroup, iNode, i )
152 Sfm_ObjForEachFanin( p, iNode, iFanin, k )
153 Sfm_NtkDfs_rec( p, iFanin, vNodes, vGroups, vGroupMap, vBoxesLeft );
154 Vec_IntForEachEntry( vGroup, iNode, i )
155 Vec_IntPush( vNodes, iNode );
156 Vec_IntPush( vBoxesLeft, iGroup );
157 }
158 else
159 {
160 Sfm_ObjSetTravIdCurrent(p, iNode);
161 Sfm_ObjForEachFanin( p, iNode, iFanin, i )
162 Sfm_NtkDfs_rec( p, iFanin, vNodes, vGroups, vGroupMap, vBoxesLeft );
163 Vec_IntPush( vNodes, iNode );
164 }
165}
166Vec_Int_t * Sfm_NtkDfs( Sfm_Ntk_t * p, Vec_Wec_t * vGroups, Vec_Int_t * vGroupMap, Vec_Int_t * vBoxesLeft, int fAllBoxes )
167{
168 Vec_Int_t * vNodes;
169 int i;
170 Vec_IntClear( vBoxesLeft );
171 vNodes = Vec_IntAlloc( p->nObjs );
172 Sfm_NtkIncrementTravId( p );
173 if ( fAllBoxes )
174 {
175 Vec_Int_t * vGroup;
176 Vec_WecForEachLevel( vGroups, vGroup, i )
177 Sfm_NtkDfs_rec( p, Vec_IntEntry(vGroup, 0), vNodes, vGroups, vGroupMap, vBoxesLeft );
178 }
179 Sfm_NtkForEachPo( p, i )
180 Sfm_NtkDfs_rec( p, Sfm_ObjFanin(p, i, 0), vNodes, vGroups, vGroupMap, vBoxesLeft );
181 return vNodes;
182}
183
195int Sfm_NtkCheckOverlap_rec( Sfm_Ntk_t * p, int iThis, int iNode )
196{
197 int i, iFanin;
198 if ( Sfm_ObjIsTravIdCurrent2(p, iThis) || iThis == iNode )
199 return 0;
200// if ( Sfm_ObjIsTravIdCurrent(p, iThis) )
201 if ( Sfm_ObjIsTravIdPrevious(p, iThis) )
202 return 1;
203 Sfm_ObjSetTravIdCurrent2(p, iThis);
204 Sfm_ObjForEachFanin( p, iThis, iFanin, i )
205 if ( Sfm_NtkCheckOverlap_rec(p, iFanin, iNode) )
206 return 1;
207 return 0;
208}
209int Sfm_NtkCheckOverlap( Sfm_Ntk_t * p, int iFan, int iNode )
210{
211 Sfm_NtkIncrementTravId2( p );
212 return Sfm_NtkCheckOverlap_rec( p, iFan, iNode );
213}
214
226static inline int Sfm_NtkCheckRoot( Sfm_Ntk_t * p, int iNode, int nLevelMax )
227{
228 int i, iFanout;
229 // the node is the root if one of the following is true:
230 // (1) the node has more than fanouts than the limit or has no fanouts (should not happen in general)
231 if ( Sfm_ObjFanoutNum(p, iNode) == 0 || Sfm_ObjFanoutNum(p, iNode) > p->pPars->nFanoutMax )
232 return 1;
233 // (2) the node has CO fanouts
234 // (3) the node has fanouts above the cutoff level
235 Sfm_ObjForEachFanout( p, iNode, iFanout, i )
236 if ( Sfm_ObjIsPo(p, iFanout) || Sfm_ObjLevel(p, iFanout) > nLevelMax )//|| !Sfm_NtkCheckOverlap(p, iFanout, iNode) )
237 return 1;
238 return 0;
239}
240void Sfm_NtkComputeRoots_rec( Sfm_Ntk_t * p, int iNode, int nLevelMax, Vec_Int_t * vRoots, Vec_Int_t * vTfo )
241{
242 int i, iFanout;
243 assert( Sfm_ObjIsNode(p, iNode) );
244 if ( Sfm_ObjIsTravIdCurrent(p, iNode) )
245 return;
246 Sfm_ObjSetTravIdCurrent(p, iNode);
247 if ( iNode != p->iPivotNode )
248 Vec_IntPush( vTfo, iNode );
249 // check if the node should be the root
250 if ( Sfm_NtkCheckRoot( p, iNode, nLevelMax ) )
251 Vec_IntPush( vRoots, iNode );
252 else // if not, explore its fanouts
253 Sfm_ObjForEachFanout( p, iNode, iFanout, i )
254 Sfm_NtkComputeRoots_rec( p, iFanout, nLevelMax, vRoots, vTfo );
255}
256
268void Sfm_NtkAddDivisors( Sfm_Ntk_t * p, int iNode, int nLevelMax )
269{
270 int i, iFanout;
271 Sfm_ObjForEachFanout( p, iNode, iFanout, i )
272 {
273 // skip some of the fanouts if the number is large
274 if ( p->pPars->nFanoutMax && i > p->pPars->nFanoutMax )
275 return;
276 // skip TFI nodes, PO nodes, or nodes with high logic level
277 if ( Sfm_ObjIsTravIdCurrent(p, iFanout) || Sfm_ObjIsPo(p, iFanout) || Sfm_ObjLevel(p, iFanout) > nLevelMax )
278 continue;
279 // handle single-input nodes
280 if ( Sfm_ObjFaninNum(p, iFanout) == 1 )
281 Vec_IntPush( p->vDivs, iFanout );
282 // visit node for the first time
283 else if ( !Sfm_ObjIsTravIdCurrent2(p, iFanout) )
284 {
285 assert( Sfm_ObjFaninNum(p, iFanout) > 1 );
286 Sfm_ObjSetTravIdCurrent2( p, iFanout );
287 Sfm_ObjResetFaninCount( p, iFanout );
288 }
289 // visit node again
290 else if ( Sfm_ObjUpdateFaninCount(p, iFanout) == 0 )
291 Vec_IntPush( p->vDivs, iFanout );
292 }
293}
294
306static inline int Sfm_ObjIsUseful( Sfm_Ntk_t * p, int iNode )
307{
308 int i, iFanout;
309 if ( !Sfm_ObjIsFixed(p, iNode) )
310 return 1;
311 Sfm_ObjForEachFanout( p, iNode, iFanout, i )
312 if ( !Sfm_ObjIsFixed(p, iFanout) )
313 return 1;
314 return 0;
315}
316
328int Sfm_NtkCollectTfi_rec( Sfm_Ntk_t * p, int iNode, Vec_Int_t * vNodes )
329{
330 int i, iFanin;
331 if ( Sfm_ObjIsTravIdCurrent( p, iNode ) )
332 return 0;
333 Sfm_ObjSetTravIdCurrent( p, iNode );
334 Sfm_ObjForEachFanin( p, iNode, iFanin, i )
335 if ( Sfm_NtkCollectTfi_rec( p, iFanin, vNodes ) )
336 return 1;
337 Vec_IntPush( vNodes, iNode );
338 return p->pPars->nWinSizeMax && (Vec_IntSize(vNodes) > p->pPars->nWinSizeMax);
339}
340int Sfm_NtkCreateWindow( Sfm_Ntk_t * p, int iNode, int fVerbose )
341{
342 int i, k, iTemp;
343 abctime clkDiv, clkWin = Abc_Clock();
344
345 assert( Sfm_ObjIsNode( p, iNode ) );
346 p->iPivotNode = iNode;
347 Vec_IntClear( p->vNodes ); // internal
348 Vec_IntClear( p->vDivs ); // divisors
349 Vec_IntClear( p->vRoots ); // roots
350 Vec_IntClear( p->vTfo ); // roots
351 Vec_IntClear( p->vOrder ); // variable order
352
353 // collect transitive fanin
354 Sfm_NtkIncrementTravId( p );
355 if ( Sfm_NtkCollectTfi_rec( p, iNode, p->vNodes ) )
356 {
357 p->nMaxDivs++;
358 p->timeWin += Abc_Clock() - clkWin;
359 return 0;
360 }
361
362 // create divisors
363 clkDiv = Abc_Clock();
364 Vec_IntClear( p->vDivs );
365 Vec_IntAppend( p->vDivs, p->vNodes );
366 Vec_IntPop( p->vDivs );
367 // add non-topological divisors
368 if ( !p->pPars->nWinSizeMax || Vec_IntSize(p->vDivs) < p->pPars->nWinSizeMax + 0 )
369 {
370 Sfm_NtkIncrementTravId2( p );
371 Vec_IntForEachEntry( p->vDivs, iTemp, i )
372 if ( !p->pPars->nWinSizeMax || Vec_IntSize(p->vDivs) < p->pPars->nWinSizeMax + 0 )
373// Sfm_NtkAddDivisors( p, iTemp, Sfm_ObjLevel(p, iNode) - 1 );
374 Sfm_NtkAddDivisors( p, iTemp, p->nLevelMax - Sfm_ObjLevelR(p, iNode) );
375 }
376 if ( p->pPars->nWinSizeMax && Vec_IntSize(p->vDivs) > p->pPars->nWinSizeMax )
377 {
378/*
379 k = 0;
380 Vec_IntForEachEntryStart( p->vDivs, iTemp, i, Vec_IntSize(p->vDivs) - p->pPars->nWinSizeMax )
381 Vec_IntWriteEntry( p->vDivs, k++, iTemp );
382 assert( k == p->pPars->nWinSizeMax );
383*/
384 Vec_IntShrink( p->vDivs, p->pPars->nWinSizeMax );
385 }
386 assert( !p->pPars->nWinSizeMax || Vec_IntSize(p->vDivs) <= p->pPars->nWinSizeMax );
387 p->nMaxDivs += (int)(p->pPars->nWinSizeMax && Vec_IntSize(p->vDivs) == p->pPars->nWinSizeMax);
388 // remove node/fanins from divisors
389 // mark fanins
390 Sfm_NtkIncrementTravId2( p );
391 Sfm_ObjSetTravIdCurrent2( p, iNode );
392 Sfm_ObjForEachFanin( p, iNode, iTemp, i )
393 Sfm_ObjSetTravIdCurrent2( p, iTemp );
394 // compact divisors
395 k = 0;
396 Vec_IntForEachEntry( p->vDivs, iTemp, i )
397 if ( !Sfm_ObjIsTravIdCurrent2(p, iTemp) && Sfm_ObjIsUseful(p, iTemp) )
398 Vec_IntWriteEntry( p->vDivs, k++, iTemp );
399 Vec_IntShrink( p->vDivs, k );
400 assert( !p->pPars->nWinSizeMax || Vec_IntSize(p->vDivs) <= p->pPars->nWinSizeMax );
401 clkDiv = Abc_Clock() - clkDiv;
402 p->timeDiv += clkDiv;
403 p->nTotalDivs += Vec_IntSize(p->vDivs);
404
405 // collect TFO and window roots
406 if ( p->pPars->nTfoLevMax > 0 && !Sfm_NtkCheckRoot(p, iNode, Sfm_ObjLevel(p, iNode) + p->pPars->nTfoLevMax) )
407 {
408 // explore transitive fanout
409 Sfm_NtkIncrementTravId( p );
410 Sfm_NtkComputeRoots_rec( p, iNode, Sfm_ObjLevel(p, iNode) + p->pPars->nTfoLevMax, p->vRoots, p->vTfo );
411 assert( Vec_IntSize(p->vRoots) > 0 );
412 assert( Vec_IntSize(p->vTfo) > 0 );
413 // compute new leaves and nodes
414 Sfm_NtkIncrementTravId( p );
415 Vec_IntForEachEntry( p->vRoots, iTemp, i )
416 if ( Sfm_NtkCollectTfi_rec( p, iTemp, p->vOrder ) )
417 {
418 Vec_IntClear( p->vRoots );
419 Vec_IntClear( p->vTfo );
420 Vec_IntClear( p->vOrder );
421 break;
422 }
423 if ( Vec_IntSize(p->vRoots) > 0 )
424 Vec_IntForEachEntry( p->vTfo, iTemp, i )
425 if ( Sfm_NtkCollectTfi_rec( p, iTemp, p->vOrder ) )
426 {
427 Vec_IntClear( p->vRoots );
428 Vec_IntClear( p->vTfo );
429 Vec_IntClear( p->vOrder );
430 break;
431 }
432 if ( Vec_IntSize(p->vRoots) > 0 )
433 Vec_IntForEachEntry( p->vDivs, iTemp, i )
434 if ( Sfm_NtkCollectTfi_rec( p, iTemp, p->vOrder ) )
435 {
436 Vec_IntClear( p->vRoots );
437 Vec_IntClear( p->vTfo );
438 Vec_IntClear( p->vOrder );
439 break;
440 }
441 }
442
443 if ( Vec_IntSize(p->vOrder) == 0 )
444 {
445 int Temp = p->pPars->nWinSizeMax;
446 p->pPars->nWinSizeMax = 0;
447 Sfm_NtkIncrementTravId( p );
448 Sfm_NtkCollectTfi_rec( p, iNode, p->vOrder );
449 Vec_IntForEachEntry( p->vDivs, iTemp, i )
450 Sfm_NtkCollectTfi_rec( p, iTemp, p->vOrder );
451 p->pPars->nWinSizeMax = Temp;
452 }
453
454 // statistics
455 p->timeWin += Abc_Clock() - clkWin - clkDiv;
456 if ( !fVerbose )
457 return 1;
458
459 // print stats about the window
460 printf( "%6d : ", iNode );
461 printf( "Leaves = %5d. ", 0 );
462 printf( "Nodes = %5d. ", Vec_IntSize(p->vNodes) );
463 printf( "Roots = %5d. ", Vec_IntSize(p->vRoots) );
464 printf( "Divs = %5d. ", Vec_IntSize(p->vDivs) );
465 printf( "\n" );
466 return 1;
467}
468void Sfm_NtkWindowTest( Sfm_Ntk_t * p, int iNode )
469{
470 int i;
472 Sfm_NtkCreateWindow( p, i, 1 );
473}
474
478
479
481
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
Cube * p
Definition exorList.c:222
#define Sfm_ObjForEachFanin(p, Node, Fan, i)
Definition sfmInt.h:199
#define Sfm_NtkForEachPo(p, i)
Definition sfmInt.h:196
#define Sfm_NtkForEachNode(p, i)
Definition sfmInt.h:197
#define Sfm_ObjForEachFanout(p, Node, Fan, i)
Definition sfmInt.h:200
int Sfm_NtkCreateWindow(Sfm_Ntk_t *p, int iNode, int fVerbose)
Definition sfmWin.c:340
int Sfm_ObjDeref(Sfm_Ntk_t *p, int iObj)
Definition sfmWin.c:82
void Sfm_NtkWindowTest(Sfm_Ntk_t *p, int iNode)
Definition sfmWin.c:468
ABC_NAMESPACE_IMPL_START int Sfm_ObjRef_rec(Sfm_Ntk_t *p, int iObj)
DECLARATIONS ///.
Definition sfmWin.c:45
void Sfm_NtkDfs_rec(Sfm_Ntk_t *p, int iNode, Vec_Int_t *vNodes, Vec_Wec_t *vGroups, Vec_Int_t *vGroupMap, Vec_Int_t *vBoxesLeft)
Definition sfmWin.c:136
int Sfm_NtkCheckOverlap_rec(Sfm_Ntk_t *p, int iThis, int iNode)
Definition sfmWin.c:195
int Sfm_ObjDeref_rec(Sfm_Ntk_t *p, int iObj)
Definition sfmWin.c:67
int Sfm_NtkCollectTfi_rec(Sfm_Ntk_t *p, int iNode, Vec_Int_t *vNodes)
Definition sfmWin.c:328
Vec_Int_t * Sfm_NtkDfs(Sfm_Ntk_t *p, Vec_Wec_t *vGroups, Vec_Int_t *vGroupMap, Vec_Int_t *vBoxesLeft, int fAllBoxes)
Definition sfmWin.c:166
void Sfm_NtkComputeRoots_rec(Sfm_Ntk_t *p, int iNode, int nLevelMax, Vec_Int_t *vRoots, Vec_Int_t *vTfo)
Definition sfmWin.c:240
int Sfm_NtkCheckOverlap(Sfm_Ntk_t *p, int iFan, int iNode)
Definition sfmWin.c:209
void Sfm_NtkAddDivisors(Sfm_Ntk_t *p, int iNode, int nLevelMax)
Definition sfmWin.c:268
int Sfm_ObjMffcSize(Sfm_Ntk_t *p, int iObj)
Definition sfmWin.c:89
int Sfm_ObjRef(Sfm_Ntk_t *p, int iObj)
Definition sfmWin.c:60
typedefABC_NAMESPACE_HEADER_START struct Sfm_Ntk_t_ Sfm_Ntk_t
INCLUDES ///.
Definition sfm.h:41
#define assert(ex)
Definition util_old.h:213
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
Definition vecWec.h:55
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.
Definition vecWec.h:42