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