1 /**CFile****************************************************************
2
3 FileName [abcMfs.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [Network and node package.]
8
9 Synopsis [Optimization with don't-cares.]
10
11 Author [Alan Mishchenko]
12
13 Affiliation [UC Berkeley]
14
15 Date [Ver. 1.0. Started - June 20, 2005.]
16
17 Revision [$Id: abcMfs.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18
19 ***********************************************************************/
20
21 #include "base/abc/abc.h"
22 #include "bool/kit/kit.h"
23 #include "opt/sfm/sfm.h"
24 #include "base/io/ioAbc.h"
25
26 ABC_NAMESPACE_IMPL_START
27
28
29 ////////////////////////////////////////////////////////////////////////
30 /// DECLARATIONS ///
31 ////////////////////////////////////////////////////////////////////////
32
33 ////////////////////////////////////////////////////////////////////////
34 /// FUNCTION DEFINITIONS ///
35 ////////////////////////////////////////////////////////////////////////
36
37 /**Function*************************************************************
38
39 Synopsis []
40
41 Description []
42
43 SideEffects []
44
45 SeeAlso []
46
47 ***********************************************************************/
Abc_NtkAssignIDs(Abc_Ntk_t * pNtk)48 Vec_Ptr_t * Abc_NtkAssignIDs( Abc_Ntk_t * pNtk )
49 {
50 Vec_Ptr_t * vNodes;
51 Abc_Obj_t * pObj;
52 int i;
53 vNodes = Abc_NtkDfs( pNtk, 0 );
54 Abc_NtkCleanCopy( pNtk );
55 Abc_NtkForEachCi( pNtk, pObj, i )
56 pObj->iTemp = i;
57 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
58 pObj->iTemp = Abc_NtkCiNum(pNtk) + i;
59 Abc_NtkForEachCo( pNtk, pObj, i )
60 pObj->iTemp = Abc_NtkCiNum(pNtk) + Vec_PtrSize(vNodes) + i;
61 return vNodes;
62 }
Abc_NtkAssignIDs2(Abc_Ntk_t * pNtk)63 Vec_Ptr_t * Abc_NtkAssignIDs2( Abc_Ntk_t * pNtk )
64 {
65 Vec_Ptr_t * vNodes;
66 Abc_Obj_t * pObj;
67 int i;
68 Abc_NtkCleanCopy( pNtk );
69 Abc_NtkForEachCi( pNtk, pObj, i )
70 pObj->iTemp = i;
71 vNodes = Vec_PtrAlloc( Abc_NtkNodeNum(pNtk) );
72 Abc_NtkForEachNode( pNtk, pObj, i )
73 {
74 pObj->iTemp = Abc_NtkCiNum(pNtk) + Vec_PtrSize(vNodes);
75 Vec_PtrPush( vNodes, pObj );
76 }
77 assert( Vec_PtrSize(vNodes) == Abc_NtkNodeNum(pNtk) );
78 Abc_NtkForEachCo( pNtk, pObj, i )
79 pObj->iTemp = Abc_NtkCiNum(pNtk) + Vec_PtrSize(vNodes) + i;
80 return vNodes;
81 }
82
83 /**Function*************************************************************
84
85 Synopsis [Assign truth table sizes.]
86
87 Description []
88
89 SideEffects []
90
91 SeeAlso []
92
93 ***********************************************************************/
Abc_NtkAssignStarts(Abc_Ntk_t * pNtk,Vec_Ptr_t * vNodes,int * pnTotal)94 Vec_Int_t * Abc_NtkAssignStarts( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes, int * pnTotal )
95 {
96 Abc_Obj_t * pObj; int i, Counter = 0;
97 Vec_Int_t * vStarts = Vec_IntStart( Abc_NtkObjNum(pNtk) );
98 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
99 {
100 Vec_IntWriteEntry( vStarts, pObj->iTemp, Counter );
101 Counter += Abc_Truth6WordNum( Abc_ObjFaninNum(pObj) );
102 }
103 *pnTotal = Counter;
104 return vStarts;
105 }
106
Abc_NtkFillTruthStore(word TruthStore[16][1<<10])107 void Abc_NtkFillTruthStore( word TruthStore[16][1<<10] )
108 {
109 if ( TruthStore[0][0] == 0 )
110 {
111 static word Truth6[6] = {
112 0xAAAAAAAAAAAAAAAA,
113 0xCCCCCCCCCCCCCCCC,
114 0xF0F0F0F0F0F0F0F0,
115 0xFF00FF00FF00FF00,
116 0xFFFF0000FFFF0000,
117 0xFFFFFFFF00000000
118 };
119 int nVarsMax = 16;
120 int nWordsMax = (1 << 10);
121 int i, k;
122 assert( nVarsMax <= 16 );
123 for ( i = 0; i < 6; i++ )
124 for ( k = 0; k < nWordsMax; k++ )
125 TruthStore[i][k] = Truth6[i];
126 for ( i = 6; i < nVarsMax; i++ )
127 for ( k = 0; k < nWordsMax; k++ )
128 TruthStore[i][k] = ((k >> (i-6)) & 1) ? ~(word)0 : 0;
129 }
130 }
131
132 /**Function*************************************************************
133
134 Synopsis [Extracts information about the network.]
135
136 Description []
137
138 SideEffects []
139
140 SeeAlso []
141
142 ***********************************************************************/
Abc_NtkExtractMfs(Abc_Ntk_t * pNtk,int nFirstFixed)143 Sfm_Ntk_t * Abc_NtkExtractMfs( Abc_Ntk_t * pNtk, int nFirstFixed )
144 {
145 word TruthStore[16][1<<10] = {{0}}, * pTruths[16] = {NULL}, pCube[1<<10] = {0};
146 Vec_Ptr_t * vNodes;
147 Vec_Wec_t * vFanins;
148 Vec_Str_t * vFixed;
149 Vec_Wrd_t * vTruths;
150 Vec_Int_t * vArray;
151 Vec_Int_t * vStarts;
152 Vec_Wrd_t * vTruths2;
153 Abc_Obj_t * pObj, * pFanin;
154 int i, k, nObjs, nTotal = 0;
155 vNodes = nFirstFixed ? Abc_NtkAssignIDs2(pNtk) : Abc_NtkAssignIDs(pNtk);
156 nObjs = Abc_NtkCiNum(pNtk) + Vec_PtrSize(vNodes) + Abc_NtkCoNum(pNtk);
157 vFanins = Vec_WecStart( nObjs );
158 vFixed = Vec_StrStart( nObjs );
159 vTruths = Vec_WrdStart( nObjs );
160 vStarts = Abc_NtkAssignStarts( pNtk, vNodes, &nTotal );
161 vTruths2= Vec_WrdStart( nTotal );
162 Abc_NtkFillTruthStore( TruthStore );
163 for ( i = 0; i < 16; i++ )
164 pTruths[i] = TruthStore[i];
165 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
166 {
167 if ( Abc_ObjFaninNum(pObj) <= 6 )
168 {
169 word uTruth = Abc_SopToTruth((char *)pObj->pData, Abc_ObjFaninNum(pObj));
170 Vec_WrdWriteEntry( vTruths, pObj->iTemp, uTruth );
171 if ( uTruth == 0 || ~uTruth == 0 )
172 continue;
173 }
174 else
175 {
176 int nWords = Abc_Truth6WordNum( Abc_ObjFaninNum(pObj) );
177 int Offset = Vec_IntEntry( vStarts, pObj->iTemp );
178 word * pRes = Vec_WrdEntryP( vTruths2, Offset );
179 Abc_SopToTruthBig( (char *)pObj->pData, Abc_ObjFaninNum(pObj), pTruths, pCube, pRes );
180 // check const0
181 for ( k = 0; k < nWords; k++ )
182 if ( pRes[k] )
183 break;
184 if ( k == nWords )
185 continue;
186 // check const1
187 for ( k = 0; k < nWords; k++ )
188 if ( ~pRes[k] )
189 break;
190 if ( k == nWords )
191 continue;
192 }
193 vArray = Vec_WecEntry( vFanins, pObj->iTemp );
194 Vec_IntGrow( vArray, Abc_ObjFaninNum(pObj) );
195 Abc_ObjForEachFanin( pObj, pFanin, k )
196 Vec_IntPush( vArray, pFanin->iTemp );
197 //Vec_IntPrint( vArray );
198 }
199 Abc_NtkForEachCo( pNtk, pObj, i )
200 {
201 vArray = Vec_WecEntry( vFanins, pObj->iTemp );
202 Vec_IntGrow( vArray, Abc_ObjFaninNum(pObj) );
203 Abc_ObjForEachFanin( pObj, pFanin, k )
204 Vec_IntPush( vArray, pFanin->iTemp );
205 }
206 Vec_PtrFree( vNodes );
207 for ( i = Abc_NtkCiNum(pNtk); i < Abc_NtkCiNum(pNtk) + nFirstFixed; i++ )
208 Vec_StrWriteEntry( vFixed, i, (char)1 );
209 // update fixed
210 assert( nFirstFixed >= 0 && nFirstFixed < Abc_NtkNodeNum(pNtk) );
211 // for ( i = Abc_NtkCiNum(pNtk); i + Abc_NtkCoNum(pNtk) < Abc_NtkObjNum(pNtk); i++ )
212 // if ( rand() % 10 == 0 )
213 // Vec_StrWriteEntry( vFixed, i, (char)1 );
214 return Sfm_NtkConstruct( vFanins, Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), vFixed, NULL, vTruths, vStarts, vTruths2 );
215 }
Abc_NtkExtractMfs2(Abc_Ntk_t * pNtk,int iPivot)216 Sfm_Ntk_t * Abc_NtkExtractMfs2( Abc_Ntk_t * pNtk, int iPivot )
217 {
218 word TruthStore[16][1<<10] = {{0}}, * pTruths[16] = {NULL}, pCube[1<<10] = {0};
219 Vec_Ptr_t * vNodes;
220 Vec_Wec_t * vFanins;
221 Vec_Str_t * vFixed;
222 Vec_Wrd_t * vTruths;
223 Vec_Int_t * vArray;
224 Vec_Int_t * vStarts;
225 Vec_Wrd_t * vTruths2;
226 Abc_Obj_t * pObj, * pFanin;
227 int i, k, nObjs, nTotal = 0;
228 vNodes = Abc_NtkAssignIDs2(pNtk);
229 nObjs = Abc_NtkCiNum(pNtk) + Vec_PtrSize(vNodes) + Abc_NtkCoNum(pNtk);
230 vFanins = Vec_WecStart( nObjs );
231 vFixed = Vec_StrStart( nObjs );
232 vTruths = Vec_WrdStart( nObjs );
233 vStarts = Abc_NtkAssignStarts( pNtk, vNodes, &nTotal );
234 vTruths2= Vec_WrdAlloc( nTotal );
235 Abc_NtkFillTruthStore( TruthStore );
236 for ( i = 0; i < 16; i++ )
237 pTruths[i] = TruthStore[i];
238 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
239 {
240 if ( Abc_ObjFaninNum(pObj) <= 6 )
241 {
242 word uTruth = Abc_SopToTruth((char *)pObj->pData, Abc_ObjFaninNum(pObj));
243 Vec_WrdWriteEntry( vTruths, pObj->iTemp, uTruth );
244 if ( uTruth == 0 || ~uTruth == 0 )
245 continue;
246 }
247 else
248 {
249 int nWords = Abc_Truth6WordNum( Abc_ObjFaninNum(pObj) );
250 int Offset = Vec_IntEntry( vStarts, pObj->iTemp );
251 word * pRes = Vec_WrdEntryP( vTruths2, Offset );
252 Abc_SopToTruthBig( (char *)pObj->pData, Abc_ObjFaninNum(pObj), pTruths, pCube, pRes );
253 // check const0
254 for ( k = 0; k < nWords; k++ )
255 if ( pRes[k] )
256 break;
257 if ( k == nWords )
258 continue;
259 // check const1
260 for ( k = 0; k < nWords; k++ )
261 if ( ~pRes[k] )
262 break;
263 if ( k == nWords )
264 continue;
265 }
266 vArray = Vec_WecEntry( vFanins, pObj->iTemp );
267 Vec_IntGrow( vArray, Abc_ObjFaninNum(pObj) );
268 Abc_ObjForEachFanin( pObj, pFanin, k )
269 Vec_IntPush( vArray, pFanin->iTemp );
270 }
271 Abc_NtkForEachCo( pNtk, pObj, i )
272 {
273 vArray = Vec_WecEntry( vFanins, pObj->iTemp );
274 Vec_IntGrow( vArray, Abc_ObjFaninNum(pObj) );
275 Abc_ObjForEachFanin( pObj, pFanin, k )
276 Vec_IntPush( vArray, pFanin->iTemp );
277 }
278 Vec_PtrFree( vNodes );
279 // set fixed attributes
280 Abc_NtkForEachNode( pNtk, pObj, i )
281 if ( i >= iPivot )
282 Vec_StrWriteEntry( vFixed, pObj->iTemp, (char)1 );
283 return Sfm_NtkConstruct( vFanins, Abc_NtkCiNum(pNtk), Abc_NtkCoNum(pNtk), vFixed, NULL, vTruths, vStarts, vTruths2 );
284 }
285
286 /**Function*************************************************************
287
288 Synopsis []
289
290 Description []
291
292 SideEffects []
293
294 SeeAlso []
295
296 ***********************************************************************/
Abc_NtkInsertMfs(Abc_Ntk_t * pNtk,Sfm_Ntk_t * p)297 void Abc_NtkInsertMfs( Abc_Ntk_t * pNtk, Sfm_Ntk_t * p )
298 {
299 Vec_Int_t * vCover, * vMap, * vArray;
300 Abc_Obj_t * pNode;
301 word * pTruth;
302 int i, k, Fanin;
303 // map new IDs into old nodes
304 vMap = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
305 Abc_NtkForEachCi( pNtk, pNode, i )
306 Vec_IntWriteEntry( vMap, pNode->iTemp, Abc_ObjId(pNode) );
307 Abc_NtkForEachNode( pNtk, pNode, i )
308 if ( pNode->iTemp > 0 )
309 Vec_IntWriteEntry( vMap, pNode->iTemp, Abc_ObjId(pNode) );
310 // remove old fanins
311 Abc_NtkForEachNode( pNtk, pNode, i )
312 if ( !Sfm_NodeReadFixed(p, pNode->iTemp) )
313 Abc_ObjRemoveFanins( pNode );
314 // create new fanins
315 vCover = Vec_IntAlloc( 1 << 16 );
316 Abc_NtkForEachNode( pNtk, pNode, i )
317 {
318 if ( pNode->iTemp == 0 || Sfm_NodeReadFixed(p, pNode->iTemp) )
319 continue;
320 if ( !Sfm_NodeReadUsed(p, pNode->iTemp) )
321 {
322 Abc_NtkDeleteObj( pNode );
323 continue;
324 }
325 // update fanins
326 vArray = Sfm_NodeReadFanins( p, pNode->iTemp );
327 Vec_IntForEachEntry( vArray, Fanin, k )
328 Abc_ObjAddFanin( pNode, Abc_NtkObj(pNtk, Vec_IntEntry(vMap, Fanin)) );
329 pTruth = Sfm_NodeReadTruth( p, pNode->iTemp );
330 pNode->pData = Abc_SopCreateFromTruthIsop( (Mem_Flex_t *)pNtk->pManFunc, Vec_IntSize(vArray), pTruth, vCover );
331 assert( Abc_SopGetVarNum((char *)pNode->pData) == Vec_IntSize(vArray) );
332 }
333 Vec_IntFree( vCover );
334 Vec_IntFree( vMap );
335 }
336
337 /**Function*************************************************************
338
339 Synopsis []
340
341 Description []
342
343 SideEffects []
344
345 SeeAlso []
346
347 ***********************************************************************/
Abc_NtkPerformMfs(Abc_Ntk_t * pNtk,Sfm_Par_t * pPars)348 int Abc_NtkPerformMfs( Abc_Ntk_t * pNtk, Sfm_Par_t * pPars )
349 {
350 Sfm_Ntk_t * p;
351 int nFaninMax, nNodes;
352 assert( Abc_NtkIsLogic(pNtk) );
353 Abc_NtkSweep( pNtk, 0 );
354 // count fanouts
355 nFaninMax = Abc_NtkGetFaninMax( pNtk );
356 if ( nFaninMax > 15 )
357 {
358 Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 15 fanins.\n" );
359 return 1;
360 }
361 if ( !Abc_NtkHasSop(pNtk) )
362 if ( !Abc_NtkToSop( pNtk, -1, ABC_INFINITY ) )
363 {
364 printf( "Conversion to SOP has failed due to low resource limit.\n" );
365 return 0;
366 }
367 // collect information
368 p = Abc_NtkExtractMfs( pNtk, pPars->nFirstFixed );
369 // perform optimization
370 nNodes = Sfm_NtkPerform( p, pPars );
371 if ( nNodes == 0 )
372 {
373 // Abc_Print( 1, "The network is not changed by \"mfs\".\n" );
374 }
375 else
376 {
377 Abc_NtkInsertMfs( pNtk, p );
378 if( pPars->fVerbose )
379 Abc_Print( 1, "The network has %d nodes changed by \"mfs\".\n", nNodes );
380 }
381 Sfm_NtkFree( p );
382 return 1;
383 }
384
385
386
387 /**Function*************************************************************
388
389 Synopsis [Unrolls logic network while dropping some next-state functions.]
390
391 Description [Returns the unrolled network.]
392
393 SideEffects []
394
395 SeeAlso []
396
397 ***********************************************************************/
Abc_NtkUnrollAndDrop(Abc_Ntk_t * p,int nFrames,int nFramesAdd,Vec_Int_t * vFlops,int * piPivot)398 Abc_Ntk_t * Abc_NtkUnrollAndDrop( Abc_Ntk_t * p, int nFrames, int nFramesAdd, Vec_Int_t * vFlops, int * piPivot )
399 {
400 Abc_Ntk_t * pNtk;
401 Abc_Obj_t * pFanin, * pNode;
402 Vec_Ptr_t * vNodes;
403 int i, k, f, Value;
404 assert( nFramesAdd >= 0 );
405 assert( Abc_NtkIsLogic(p) );
406 assert( Vec_IntSize(vFlops) == Abc_NtkLatchNum(p) );
407 *piPivot = -1;
408 // start the network
409 pNtk = Abc_NtkAlloc( p->ntkType, p->ntkFunc, 1 );
410 pNtk->pName = Extra_UtilStrsav(Abc_NtkName(p));
411 // add CIs for the new network
412 Abc_NtkForEachCi( p, pNode, i )
413 pNode->pCopy = Abc_NtkCreatePi( pNtk );
414 // iterate unrolling
415 vNodes = Abc_NtkDfs( p, 0 );
416 for ( f = 0; f <= nFrames + nFramesAdd; f++ )
417 {
418 if ( f > 0 )
419 {
420 Abc_NtkForEachPi( p, pNode, i )
421 pNode->pCopy = Abc_NtkCreatePi( pNtk );
422 }
423 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
424 {
425 Abc_NtkDupObj( pNtk, pNode, 0 );
426 Abc_ObjForEachFanin( pNode, pFanin, k )
427 Abc_ObjAddFanin( pNode->pCopy, pFanin->pCopy );
428 }
429 Abc_NtkForEachCo( p, pNode, i )
430 pNode->pCopy = Abc_ObjFanin0(pNode)->pCopy;
431 Abc_NtkForEachPo( p, pNode, i )
432 Abc_ObjAddFanin( Abc_NtkCreatePo(pNtk), pNode->pCopy );
433 // add buffers
434 if ( f == 0 )
435 {
436 *piPivot = Abc_NtkObjNum(pNtk);
437 // Abc_NtkForEachLatchInput( p, pNode, i )
438 // pNode->pCopy = Abc_NtkCreateNodeBuf( pNtk, pNode->pCopy );
439 }
440 // transfer to flop outputs
441 Abc_NtkForEachLatch( p, pNode, i )
442 Abc_ObjFanout0(pNode)->pCopy = Abc_ObjFanin0(pNode)->pCopy;
443 // add final POs
444 if ( f > nFramesAdd )
445 {
446 Vec_IntForEachEntry( vFlops, Value, i )
447 {
448 if ( Value == 0 )
449 continue;
450 pNode = Abc_NtkCo( p, Abc_NtkPoNum(p) + i );
451 Abc_ObjAddFanin( Abc_NtkCreatePo(pNtk), pNode->pCopy );
452 }
453 }
454 }
455 Vec_PtrFree( vNodes );
456 Abc_NtkAddDummyPiNames( pNtk );
457 Abc_NtkAddDummyPoNames( pNtk );
458 // perform combinational cleanup
459 Abc_NtkCleanup( pNtk, 0 );
460 if ( !Abc_NtkCheck( pNtk ) )
461 fprintf( stdout, "Abc_NtkCreateFromNode(): Network check has failed.\n" );
462 return pNtk;
463 }
464
465 /**Function*************************************************************
466
467 Synopsis [Updates the original network to include optimized nodes.]
468
469 Description []
470
471 SideEffects []
472
473 SeeAlso []
474
475 ***********************************************************************/
Abc_NtkReinsertNodes(Abc_Ntk_t * p,Abc_Ntk_t * pNtk,int iPivot)476 void Abc_NtkReinsertNodes( Abc_Ntk_t * p, Abc_Ntk_t * pNtk, int iPivot )
477 {
478 Abc_Obj_t * pNode, * pNodeNew, * pFaninNew;
479 Vec_Ptr_t * vNodes;
480 int i, k;
481 assert( Abc_NtkIsLogic(p) );
482 assert( Abc_NtkCiNum(p) <= Abc_NtkCiNum(pNtk) );
483 vNodes = Abc_NtkDfs( p, 0 );
484 // clean old network
485 Abc_NtkCleanCopy( p );
486 Abc_NtkForEachNode( p, pNode, i )
487 {
488 Abc_ObjRemoveFanins( pNode );
489 pNode->pData = Abc_SopRegister( (Mem_Flex_t *)p->pManFunc, (char *)" 0\n" );
490 }
491 // map CIs
492 Abc_NtkForEachCi( p, pNode, i )
493 Abc_NtkCi(pNtk, i)->pCopy = pNode;
494 // map internal nodes
495 assert( Vec_PtrSize(vNodes) + Abc_NtkCiNum(p) + Abc_NtkPoNum(p) == iPivot );
496 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
497 {
498 pNodeNew = Abc_NtkObj( pNtk, Abc_NtkCiNum(p) + i + 1 );
499 if ( pNodeNew == NULL )
500 continue;
501 pNodeNew->pCopy = pNode;
502 }
503 // connect internal nodes
504 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNode, i )
505 {
506 pNodeNew = Abc_NtkObj( pNtk, Abc_NtkCiNum(p) + i + 1 );
507 if ( pNodeNew == NULL )
508 continue;
509 assert( pNodeNew->pCopy == pNode );
510 Abc_ObjForEachFanin( pNodeNew, pFaninNew, k )
511 Abc_ObjAddFanin( pNodeNew->pCopy, pFaninNew->pCopy );
512 pNode->pData = Abc_SopRegister( (Mem_Flex_t *)p->pManFunc, (char *)pNodeNew->pData );
513 }
514 Vec_PtrFree( vNodes );
515 }
516
517 /**Function*************************************************************
518
519 Synopsis [Performs MFS for the unrolled network.]
520
521 Description []
522
523 SideEffects []
524
525 SeeAlso []
526
527 ***********************************************************************/
Abc_NtkMfsAfterICheck(Abc_Ntk_t * p,int nFrames,int nFramesAdd,Vec_Int_t * vFlops,Sfm_Par_t * pPars)528 int Abc_NtkMfsAfterICheck( Abc_Ntk_t * p, int nFrames, int nFramesAdd, Vec_Int_t * vFlops, Sfm_Par_t * pPars )
529 {
530 Sfm_Ntk_t * pp;
531 int nFaninMax, nNodes;
532 Abc_Ntk_t * pNtk;
533 int iPivot;
534 assert( Abc_NtkIsLogic(p) );
535 // count fanouts
536 nFaninMax = Abc_NtkGetFaninMax( p );
537 if ( nFaninMax > 15 )
538 {
539 Abc_Print( 1, "Currently \"mfs\" cannot process the network containing nodes with more than 15 fanins.\n" );
540 return 0;
541 }
542 if ( !Abc_NtkHasSop(p) )
543 Abc_NtkToSop( p, -1, ABC_INFINITY );
544 // derive unfolded network
545 pNtk = Abc_NtkUnrollAndDrop( p, nFrames, nFramesAdd, vFlops, &iPivot );
546 Io_WriteBlifLogic( pNtk, "unroll_dump.blif", 0 );
547 // collect information
548 pp = Abc_NtkExtractMfs2( pNtk, iPivot );
549 // perform optimization
550 nNodes = Sfm_NtkPerform( pp, pPars );
551 if ( nNodes == 0 )
552 {
553 // Abc_Print( 1, "The network is not changed by \"mfs\".\n" );
554 }
555 else
556 {
557 Abc_NtkInsertMfs( pNtk, pp );
558 if( pPars->fVerbose )
559 Abc_Print( 1, "The network has %d nodes changed by \"mfs\".\n", nNodes );
560 Abc_NtkReinsertNodes( p, pNtk, iPivot );
561 }
562 Abc_NtkDelete( pNtk );
563 Sfm_NtkFree( pp );
564 // perform final sweep
565 Abc_NtkSweep( p, 0 );
566 if ( !Abc_NtkHasSop(p) )
567 Abc_NtkToSop( p, -1, ABC_INFINITY );
568 return 1;
569
570 }
571
572
573 ////////////////////////////////////////////////////////////////////////
574 /// END OF FILE ///
575 ////////////////////////////////////////////////////////////////////////
576
577
578 ABC_NAMESPACE_IMPL_END
579
580