1 /**CFile****************************************************************
2 
3   FileName    [aigScl.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [AIG package.]
8 
9   Synopsis    [Sequential cleanup.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - April 28, 2007.]
16 
17   Revision    [$Id: aigScl.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "aig.h"
22 
23 ABC_NAMESPACE_IMPL_START
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 ///                        DECLARATIONS                              ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 ////////////////////////////////////////////////////////////////////////
31 ///                     FUNCTION DEFINITIONS                         ///
32 ////////////////////////////////////////////////////////////////////////
33 
34 /**Function*************************************************************
35 
36   Synopsis    [Remaps the manager.]
37 
38   Description [Map in the array specifies for each CI node the node that
39   should be used after remapping.]
40 
41   SideEffects []
42 
43   SeeAlso     []
44 
45 ***********************************************************************/
Aig_ManRemap(Aig_Man_t * p,Vec_Ptr_t * vMap)46 Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap )
47 {
48     Aig_Man_t * pNew;
49     Aig_Obj_t * pObj, * pObjMapped;
50     int i, nTruePis;
51     // create the new manager
52     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
53     pNew->pName = Abc_UtilStrsav( p->pName );
54     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
55     pNew->nAsserts = p->nAsserts;
56     pNew->nConstrs = p->nConstrs;
57     pNew->nBarBufs = p->nBarBufs;
58     assert( p->vFlopNums == NULL || Vec_IntSize(p->vFlopNums) == p->nRegs );
59     if ( p->vFlopNums )
60         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
61     if ( p->vFlopReprs )
62         pNew->vFlopReprs = Vec_IntDup( p->vFlopReprs );
63     // create the PIs
64     Aig_ManCleanData( p );
65     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
66     Aig_ManForEachCi( p, pObj, i )
67         pObj->pData = Aig_ObjCreateCi(pNew);
68     // implement the mapping
69     nTruePis = Aig_ManCiNum(p)-Aig_ManRegNum(p);
70     if ( p->vFlopReprs )
71     {
72         Aig_ManForEachLoSeq( p, pObj, i )
73             pObj->pNext = (Aig_Obj_t *)(long)Vec_IntEntry( p->vFlopNums, i-nTruePis );
74     }
75     Aig_ManForEachCi( p, pObj, i )
76     {
77         pObjMapped = (Aig_Obj_t *)Vec_PtrEntry( vMap, i );
78         pObj->pData = Aig_NotCond( (Aig_Obj_t *)Aig_Regular(pObjMapped)->pData, Aig_IsComplement(pObjMapped) );
79         if ( pNew->vFlopReprs && i >= nTruePis && pObj != pObjMapped )
80         {
81             Vec_IntPush( pNew->vFlopReprs, Aig_ObjCioId(pObj) );
82             if ( Aig_ObjIsConst1( Aig_Regular(pObjMapped) ) )
83                 Vec_IntPush( pNew->vFlopReprs, -1 );
84             else
85             {
86                 assert( !Aig_IsComplement(pObjMapped) );
87                 assert( Aig_ObjIsCi(pObjMapped) );
88                 assert( Aig_ObjCioId(pObj) != Aig_ObjCioId(pObjMapped) );
89                 Vec_IntPush( pNew->vFlopReprs, Aig_ObjCioId(pObjMapped) );
90             }
91         }
92     }
93     if ( p->vFlopReprs )
94     {
95         Aig_ManForEachLoSeq( p, pObj, i )
96             pObj->pNext = NULL;
97     }
98     // duplicate internal nodes
99     Aig_ManForEachObj( p, pObj, i )
100         if ( Aig_ObjIsBuf(pObj) )
101             pObj->pData = Aig_ObjChild0Copy(pObj);
102         else if ( Aig_ObjIsNode(pObj) )
103             pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
104     // add the POs
105     Aig_ManForEachCo( p, pObj, i )
106         Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
107     assert( Aig_ManNodeNum(p) >= Aig_ManNodeNum(pNew) );
108     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
109     // check the resulting network
110     if ( !Aig_ManCheck(pNew) )
111         printf( "Aig_ManRemap(): The check has failed.\n" );
112     return pNew;
113 }
114 
115 /**Function*************************************************************
116 
117   Synopsis    [Returns the number of dangling nodes removed.]
118 
119   Description []
120 
121   SideEffects []
122 
123   SeeAlso     []
124 
125 ***********************************************************************/
Aig_ManSeqCleanup_rec(Aig_Man_t * p,Aig_Obj_t * pObj,Vec_Ptr_t * vNodes)126 void Aig_ManSeqCleanup_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
127 {
128     if ( Aig_ObjIsTravIdCurrent(p, pObj) )
129         return;
130     Aig_ObjSetTravIdCurrent(p, pObj);
131     // collect latch input corresponding to unmarked PI (latch output)
132     if ( Aig_ObjIsCi(pObj) )
133     {
134         Vec_PtrPush( vNodes, pObj->pNext );
135         return;
136     }
137     if ( Aig_ObjIsCo(pObj) || Aig_ObjIsBuf(pObj) )
138     {
139         Aig_ManSeqCleanup_rec( p, Aig_ObjFanin0(pObj), vNodes );
140         return;
141     }
142     assert( Aig_ObjIsNode(pObj) );
143     Aig_ManSeqCleanup_rec( p, Aig_ObjFanin0(pObj), vNodes );
144     Aig_ManSeqCleanup_rec( p, Aig_ObjFanin1(pObj), vNodes );
145 }
146 
147 /**Function*************************************************************
148 
149   Synopsis    [Returns the number of dangling nodes removed.]
150 
151   Description []
152 
153   SideEffects []
154 
155   SeeAlso     []
156 
157 ***********************************************************************/
Aig_ManSeqCleanup(Aig_Man_t * p)158 int Aig_ManSeqCleanup( Aig_Man_t * p )
159 {
160     Vec_Ptr_t * vNodes, * vCis, * vCos;
161     Aig_Obj_t * pObj, * pObjLi, * pObjLo;
162     int i, nTruePis, nTruePos;
163 //    assert( Aig_ManBufNum(p) == 0 );
164 
165     // mark the PIs
166     Aig_ManIncrementTravId( p );
167     Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) );
168     Aig_ManForEachPiSeq( p, pObj, i )
169         Aig_ObjSetTravIdCurrent( p, pObj );
170 
171     // prepare to collect nodes reachable from POs
172     vNodes = Vec_PtrAlloc( 100 );
173     Aig_ManForEachPoSeq( p, pObj, i )
174         Vec_PtrPush( vNodes, pObj );
175 
176     // remember latch inputs in latch outputs
177     Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
178         pObjLo->pNext = pObjLi;
179     // mark the nodes reachable from these nodes
180     Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
181         Aig_ManSeqCleanup_rec( p, pObj, vNodes );
182     assert( Vec_PtrSize(vNodes) <= Aig_ManCoNum(p) );
183     // clean latch output pointers
184     Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
185         pObjLo->pNext = NULL;
186 
187     // if some latches are removed, update PIs/POs
188     if ( Vec_PtrSize(vNodes) < Aig_ManCoNum(p) )
189     {
190         if ( p->vFlopNums )
191         {
192             int nTruePos = Aig_ManCoNum(p)-Aig_ManRegNum(p);
193             int iNum, k = 0;
194             Aig_ManForEachCo( p, pObj, i )
195                 if ( i >= nTruePos && Aig_ObjIsTravIdCurrent(p, pObj) )
196                 {
197                     iNum = Vec_IntEntry( p->vFlopNums, i - nTruePos );
198                     Vec_IntWriteEntry( p->vFlopNums, k++, iNum );
199                 }
200             assert( k == Vec_PtrSize(vNodes) - nTruePos );
201             Vec_IntShrink( p->vFlopNums, k );
202         }
203         // collect new CIs/COs
204         vCis = Vec_PtrAlloc( Aig_ManCiNum(p) );
205         Aig_ManForEachCi( p, pObj, i )
206             if ( Aig_ObjIsTravIdCurrent(p, pObj) )
207                 Vec_PtrPush( vCis, pObj );
208             else
209             {
210                 Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
211 //                Aig_ManRecycleMemory( p, pObj );
212             }
213         vCos = Vec_PtrAlloc( Aig_ManCoNum(p) );
214         Aig_ManForEachCo( p, pObj, i )
215             if ( Aig_ObjIsTravIdCurrent(p, pObj) )
216                 Vec_PtrPush( vCos, pObj );
217             else
218             {
219                 Aig_ObjDisconnect( p, pObj );
220                 Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL );
221 //                Aig_ManRecycleMemory( p, pObj );
222             }
223         // remember the number of true PIs/POs
224         nTruePis = Aig_ManCiNum(p) - Aig_ManRegNum(p);
225         nTruePos = Aig_ManCoNum(p) - Aig_ManRegNum(p);
226         // set the new number of registers
227         p->nRegs -= Aig_ManCoNum(p) - Vec_PtrSize(vNodes);
228         // create new PIs/POs
229         assert( Vec_PtrSize(vCis) == nTruePis + p->nRegs );
230         assert( Vec_PtrSize(vCos) == nTruePos + p->nRegs );
231         Vec_PtrFree( p->vCis );    p->vCis = vCis;
232         Vec_PtrFree( p->vCos );    p->vCos = vCos;
233         p->nObjs[AIG_OBJ_CI] = Vec_PtrSize( p->vCis );
234         p->nObjs[AIG_OBJ_CO] = Vec_PtrSize( p->vCos );
235 
236     }
237     Vec_PtrFree( vNodes );
238     p->nTruePis = Aig_ManCiNum(p) - Aig_ManRegNum(p);
239     p->nTruePos = Aig_ManCoNum(p) - Aig_ManRegNum(p);
240     Aig_ManSetCioIds( p );
241     // remove dangling nodes
242     return Aig_ManCleanup( p );
243 }
244 
245 /**Function*************************************************************
246 
247   Synopsis    [Returns the number of dangling nodes removed.]
248 
249   Description [This cleanup procedure is different in that
250   it removes logic but does not remove the dangling latches.]
251 
252   SideEffects []
253 
254   SeeAlso     []
255 
256 ***********************************************************************/
Aig_ManSeqCleanupBasic(Aig_Man_t * p)257 int Aig_ManSeqCleanupBasic( Aig_Man_t * p )
258 {
259     Vec_Ptr_t * vNodes;
260     Aig_Obj_t * pObj, * pObjLi, * pObjLo;
261     int i;
262 //    assert( Aig_ManBufNum(p) == 0 );
263 
264     // mark the PIs
265     Aig_ManIncrementTravId( p );
266     Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) );
267     Aig_ManForEachPiSeq( p, pObj, i )
268         Aig_ObjSetTravIdCurrent( p, pObj );
269 
270     // prepare to collect nodes reachable from POs
271     vNodes = Vec_PtrAlloc( 100 );
272     Aig_ManForEachPoSeq( p, pObj, i )
273         Vec_PtrPush( vNodes, pObj );
274 
275     // remember latch inputs in latch outputs
276     Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
277         pObjLo->pNext = pObjLi;
278     // mark the nodes reachable from these nodes
279     Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
280         Aig_ManSeqCleanup_rec( p, pObj, vNodes );
281     assert( Vec_PtrSize(vNodes) <= Aig_ManCoNum(p) );
282     // clean latch output pointers
283     Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
284         pObjLo->pNext = NULL;
285 
286     // if some latches are removed, update PIs/POs
287     if ( Vec_PtrSize(vNodes) < Aig_ManCoNum(p) )
288     {
289         // add constant drivers to the dangling latches
290         Aig_ManForEachCo( p, pObj, i )
291             if ( !Aig_ObjIsTravIdCurrent(p, pObj) )
292                 Aig_ObjPatchFanin0( p, pObj, Aig_ManConst0(p) );
293     }
294     Vec_PtrFree( vNodes );
295     // remove dangling nodes
296     return Aig_ManCleanup( p );
297 }
298 
299 /**Function*************************************************************
300 
301   Synopsis    [Returns the number of dangling nodes removed.]
302 
303   Description []
304 
305   SideEffects []
306 
307   SeeAlso     []
308 
309 ***********************************************************************/
Aig_ManCountMergeRegs(Aig_Man_t * p)310 int Aig_ManCountMergeRegs( Aig_Man_t * p )
311 {
312     Aig_Obj_t * pObj, * pFanin;
313     int i, Counter = 0, Const0 = 0, Const1 = 0;
314     Aig_ManIncrementTravId( p );
315     Aig_ManForEachLiSeq( p, pObj, i )
316     {
317         pFanin = Aig_ObjFanin0(pObj);
318         if ( Aig_ObjIsConst1(pFanin) )
319         {
320             if ( Aig_ObjFaninC0(pObj) )
321                 Const0++;
322             else
323                 Const1++;
324         }
325         if ( Aig_ObjIsTravIdCurrent(p, pFanin) )
326             continue;
327         Aig_ObjSetTravIdCurrent(p, pFanin);
328         Counter++;
329     }
330     printf( "Regs = %d. Fanins = %d. Const0 = %d. Const1 = %d.\n",
331         Aig_ManRegNum(p), Counter, Const0, Const1 );
332     return 0;
333 }
334 
335 
336 /**Function*************************************************************
337 
338   Synopsis    [Checks how many latches can be reduced.]
339 
340   Description []
341 
342   SideEffects []
343 
344   SeeAlso     []
345 
346 ***********************************************************************/
Aig_ManReduceLachesCount(Aig_Man_t * p)347 int Aig_ManReduceLachesCount( Aig_Man_t * p )
348 {
349     Aig_Obj_t * pObj, * pFanin;
350     int i, Counter = 0, Diffs = 0;
351     assert( Aig_ManRegNum(p) > 0 );
352     Aig_ManForEachObj( p, pObj, i )
353         assert( !pObj->fMarkA && !pObj->fMarkB );
354     Aig_ManForEachLiSeq( p, pObj, i )
355     {
356         pFanin = Aig_ObjFanin0(pObj);
357         if ( Aig_ObjFaninC0(pObj) )
358         {
359             if ( pFanin->fMarkB )
360                 Counter++;
361             else
362                 pFanin->fMarkB = 1;
363         }
364         else
365         {
366             if ( pFanin->fMarkA )
367                 Counter++;
368             else
369                 pFanin->fMarkA = 1;
370         }
371     }
372     // count fanins that have both attributes
373     Aig_ManForEachLiSeq( p, pObj, i )
374     {
375         pFanin = Aig_ObjFanin0(pObj);
376         Diffs += pFanin->fMarkA && pFanin->fMarkB;
377         pFanin->fMarkA = pFanin->fMarkB = 0;
378     }
379 //    printf( "Diffs = %d.\n", Diffs );
380     return Counter;
381 }
382 
383 /**Function*************************************************************
384 
385   Synopsis    [Reduces the latches.]
386 
387   Description []
388 
389   SideEffects []
390 
391   SeeAlso     []
392 
393 ***********************************************************************/
Aig_ManReduceLachesOnce(Aig_Man_t * p)394 Vec_Ptr_t * Aig_ManReduceLachesOnce( Aig_Man_t * p )
395 {
396     Vec_Ptr_t * vMap;
397     Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pFanin;
398     int * pMapping, i;
399     // start mapping by adding the true PIs
400     vMap = Vec_PtrAlloc( Aig_ManCiNum(p) );
401     Aig_ManForEachPiSeq( p, pObj, i )
402         Vec_PtrPush( vMap, pObj );
403     // create mapping of fanin nodes into the corresponding latch outputs
404     pMapping = ABC_FALLOC( int, 2 * Aig_ManObjNumMax(p) );
405     Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
406     {
407         pFanin = Aig_ObjFanin0(pObjLi);
408         if ( Aig_ObjFaninC0(pObjLi) )
409         {
410             if ( pFanin->fMarkB )
411             {
412                 Vec_PtrPush( vMap, Aig_ManLo(p, pMapping[2*pFanin->Id + 1]) );
413             }
414             else
415             {
416                 pFanin->fMarkB = 1;
417                 pMapping[2*pFanin->Id + 1] = i;
418                 Vec_PtrPush( vMap, pObjLo );
419             }
420         }
421         else
422         {
423             if ( pFanin->fMarkA )
424             {
425                 Vec_PtrPush( vMap, Aig_ManLo(p, pMapping[2*pFanin->Id]) );
426             }
427             else
428             {
429                 pFanin->fMarkA = 1;
430                 pMapping[2*pFanin->Id] = i;
431                 Vec_PtrPush( vMap, pObjLo );
432             }
433         }
434     }
435     ABC_FREE( pMapping );
436     Aig_ManForEachLiSeq( p, pObj, i )
437     {
438         pFanin = Aig_ObjFanin0(pObj);
439         pFanin->fMarkA = pFanin->fMarkB = 0;
440     }
441     return vMap;
442 }
443 
444 /**Function*************************************************************
445 
446   Synopsis    [Reduces the latches.]
447 
448   Description []
449 
450   SideEffects []
451 
452   SeeAlso     []
453 
454 ***********************************************************************/
Aig_ManReduceLaches(Aig_Man_t * p,int fVerbose)455 Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose )
456 {
457     Aig_Man_t * pTemp;
458     Vec_Ptr_t * vMap;
459     int nSaved, nCur;
460     if ( fVerbose )
461         printf( "Performing combinational register sweep:\n" );
462     for ( nSaved = 0; (nCur = Aig_ManReduceLachesCount(p)); nSaved += nCur )
463     {
464 //        printf( "Reducible = %d\n", nCur );
465         vMap = Aig_ManReduceLachesOnce( p );
466         p = Aig_ManRemap( pTemp = p, vMap );
467         Vec_PtrFree( vMap );
468         Aig_ManSeqCleanup( p );
469         if ( fVerbose )
470             Aig_ManReportImprovement( pTemp, p );
471         Aig_ManStop( pTemp );
472         if ( p->nRegs == 0 )
473             break;
474     }
475     return p;
476 }
477 
478 /**Function*************************************************************
479 
480   Synopsis    [Computes strongly connected components of registers.]
481 
482   Description []
483 
484   SideEffects []
485 
486   SeeAlso     []
487 
488 ***********************************************************************/
Aig_ManComputeSccs(Aig_Man_t * p)489 void Aig_ManComputeSccs( Aig_Man_t * p )
490 {
491     Vec_Ptr_t * vSupports, * vMatrix, * vMatrix2;
492     Vec_Int_t * vSupp, * vSupp2, * vComp;
493     char * pVarsTot;
494     int i, k, m, iOut, iIn, nComps;
495     if ( Aig_ManRegNum(p) == 0 )
496     {
497         printf( "The network is combinational.\n" );
498         return;
499     }
500     // get structural supports for each output
501     vSupports = Aig_ManSupports( p );
502     // transforms the supports into the latch dependency matrix
503     vMatrix = Vec_PtrStart( Aig_ManRegNum(p) );
504     Vec_PtrForEachEntry( Vec_Int_t *, vSupports, vSupp, i )
505     {
506         // skip true POs
507         iOut = Vec_IntPop( vSupp );
508         iOut -= Aig_ManCoNum(p) - Aig_ManRegNum(p);
509         if ( iOut < 0 )
510             continue;
511         // remove PIs
512         m = 0;
513         Vec_IntForEachEntry( vSupp, iIn, k )
514         {
515             iIn -= Aig_ManCiNum(p) - Aig_ManRegNum(p);
516             if ( iIn < 0 )
517                 continue;
518             assert( iIn < Aig_ManRegNum(p) );
519             Vec_IntWriteEntry( vSupp, m++, iIn );
520         }
521         Vec_IntShrink( vSupp, m );
522         // store support in the matrix
523         assert( iOut < Aig_ManRegNum(p) );
524         Vec_PtrWriteEntry( vMatrix, iOut, vSupp );
525     }
526     // create the reverse matrix
527     vMatrix2 = Vec_PtrAlloc( Aig_ManRegNum(p) );
528     for ( i = 0; i < Aig_ManRegNum(p); i++ )
529         Vec_PtrPush( vMatrix2, Vec_IntAlloc(8) );
530     Vec_PtrForEachEntry( Vec_Int_t *, vMatrix, vSupp, i )
531     {
532         Vec_IntForEachEntry( vSupp, iIn, k )
533         {
534             vSupp2 = (Vec_Int_t *)Vec_PtrEntry( vMatrix2, iIn );
535             Vec_IntPush( vSupp2, i );
536         }
537     }
538 
539     // detect strongly connected components
540     vComp = Vec_IntAlloc( Aig_ManRegNum(p) );
541     pVarsTot = ABC_ALLOC( char, Aig_ManRegNum(p) );
542     memset( pVarsTot, 0, Aig_ManRegNum(p) * sizeof(char) );
543     for ( nComps = 0; ; nComps++ )
544     {
545         Vec_IntClear( vComp );
546         // get the first support
547         for ( iOut = 0; iOut < Aig_ManRegNum(p); iOut++ )
548             if ( pVarsTot[iOut] == 0 )
549                 break;
550         if ( iOut == Aig_ManRegNum(p) )
551             break;
552         pVarsTot[iOut] = 1;
553         Vec_IntPush( vComp, iOut );
554         Vec_IntForEachEntry( vComp, iOut, i )
555         {
556             vSupp = (Vec_Int_t *)Vec_PtrEntry( vMatrix, iOut );
557             Vec_IntForEachEntry( vSupp, iIn, k )
558             {
559                 if ( pVarsTot[iIn] )
560                     continue;
561                 pVarsTot[iIn] = 1;
562                 Vec_IntPush( vComp, iIn );
563             }
564             vSupp2 = (Vec_Int_t *)Vec_PtrEntry( vMatrix2, iOut );
565             Vec_IntForEachEntry( vSupp2, iIn, k )
566             {
567                 if ( pVarsTot[iIn] )
568                     continue;
569                 pVarsTot[iIn] = 1;
570                 Vec_IntPush( vComp, iIn );
571             }
572         }
573         if ( Vec_IntSize(vComp) == Aig_ManRegNum(p) )
574         {
575             printf( "There is only one SCC of registers in this network.\n" );
576             break;
577         }
578         printf( "SCC #%d contains %5d registers.\n", nComps+1, Vec_IntSize(vComp) );
579     }
580     ABC_FREE( pVarsTot );
581     Vec_IntFree( vComp );
582     Vec_PtrFree( vMatrix );
583     Vec_VecFree( (Vec_Vec_t *)vMatrix2 );
584     Vec_VecFree( (Vec_Vec_t *)vSupports );
585 }
586 
587 /**Function*************************************************************
588 
589   Synopsis    [Performs partitioned register sweep.]
590 
591   Description []
592 
593   SideEffects []
594 
595   SeeAlso     []
596 
597 ***********************************************************************/
Aig_ManSclPart(Aig_Man_t * pAig,int fLatchConst,int fLatchEqual,int fVerbose)598 Aig_Man_t * Aig_ManSclPart( Aig_Man_t * pAig, int fLatchConst, int fLatchEqual, int fVerbose )
599 {
600     Vec_Ptr_t * vResult;
601     Vec_Int_t * vPart;
602     int i, nCountPis, nCountRegs;
603     int * pMapBack;
604     Aig_Man_t * pTemp, * pNew;
605     int nClasses;
606 
607     if ( pAig->vClockDoms )
608     {
609         vResult = Vec_PtrAlloc( 100 );
610         Vec_PtrForEachEntry( Vec_Int_t *, (Vec_Ptr_t *)pAig->vClockDoms, vPart, i )
611             Vec_PtrPush( vResult, Vec_IntDup(vPart) );
612     }
613     else
614         vResult = Aig_ManRegPartitionSimple( pAig, 0, 0 );
615 
616     Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
617     Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i )
618     {
619         pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack );
620         Aig_ManSetRegNum( pTemp, pTemp->nRegs );
621         if (nCountPis>0)
622         {
623             pNew = Aig_ManScl( pTemp, fLatchConst, fLatchEqual, 0, -1, -1, fVerbose, 0 );
624             nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack );
625             if ( fVerbose )
626                 printf( "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d\n",
627                         i, Vec_IntSize(vPart), Aig_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), 0, nClasses );
628             Aig_ManStop( pNew );
629         }
630         Aig_ManStop( pTemp );
631         ABC_FREE( pMapBack );
632     }
633     pNew = Aig_ManDupRepr( pAig, 0 );
634     Aig_ManSeqCleanup( pNew );
635     Vec_VecFree( (Vec_Vec_t*)vResult );
636     return pNew;
637 }
638 
639 /**Function*************************************************************
640 
641   Synopsis    [Gives the current ABC network to AIG manager for processing.]
642 
643   Description []
644 
645   SideEffects []
646 
647   SeeAlso     []
648 
649 ***********************************************************************/
Aig_ManScl(Aig_Man_t * pAig,int fLatchConst,int fLatchEqual,int fUseMvSweep,int nFramesSymb,int nFramesSatur,int fVerbose,int fVeryVerbose)650 Aig_Man_t * Aig_ManScl( Aig_Man_t * pAig, int fLatchConst, int fLatchEqual, int fUseMvSweep, int nFramesSymb, int nFramesSatur, int fVerbose, int fVeryVerbose )
651 {
652     extern void Saig_ManReportUselessRegisters( Aig_Man_t * pAig );
653     extern int Saig_ManReportComplements( Aig_Man_t * p );
654 
655     Aig_Man_t * pAigInit, * pAigNew;
656     Aig_Obj_t * pFlop1, * pFlop2;
657     int i, Entry1, Entry2, nTruePis;//, nRegs;
658 
659     if ( pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0 )
660         return Aig_ManSclPart( pAig, fLatchConst, fLatchEqual, fVerbose);
661 
662     // store the original AIG
663     assert( pAig->vFlopNums == NULL );
664     pAigInit = pAig;
665     pAig = Aig_ManDupSimple( pAig );
666     // create storage for latch numbers
667     pAig->vFlopNums = Vec_IntStartNatural( pAig->nRegs );
668     pAig->vFlopReprs = Vec_IntAlloc( 100 );
669     Aig_ManSeqCleanup( pAig );
670     if ( fLatchConst && pAig->nRegs )
671         pAig = Aig_ManConstReduce( pAig, fUseMvSweep, nFramesSymb, nFramesSatur, fVerbose, fVeryVerbose );
672     if ( fLatchEqual && pAig->nRegs )
673         pAig = Aig_ManReduceLaches( pAig, fVerbose );
674     // translate pairs into reprs
675     nTruePis = Aig_ManCiNum(pAigInit)-Aig_ManRegNum(pAigInit);
676     Aig_ManReprStart( pAigInit, Aig_ManObjNumMax(pAigInit) );
677     Vec_IntForEachEntry( pAig->vFlopReprs, Entry1, i )
678     {
679         Entry2 = Vec_IntEntry( pAig->vFlopReprs, ++i );
680         pFlop1 = Aig_ManCi( pAigInit, nTruePis + Entry1 );
681         pFlop2 = (Entry2 == -1)? Aig_ManConst1(pAigInit) : Aig_ManCi( pAigInit, nTruePis + Entry2 );
682         assert( pFlop1 != pFlop2 );
683         if ( pFlop1->Id > pFlop2->Id )
684             pAigInit->pReprs[pFlop1->Id] = pFlop2;
685         else
686             pAigInit->pReprs[pFlop2->Id] = pFlop1;
687     }
688     Aig_ManStop( pAig );
689 //    Aig_ManSeqCleanup( pAigInit );
690     pAigNew = Aig_ManDupRepr( pAigInit, 0 );
691     Aig_ManSeqCleanup( pAigNew );
692 
693 //    Saig_ManReportUselessRegisters( pAigNew );
694     if ( Aig_ManRegNum(pAigNew) == 0 )
695         return pAigNew;
696 //    nRegs = Saig_ManReportComplements( pAigNew );
697 //    if ( nRegs )
698 //    printf( "The number of complemented registers = %d.\n", nRegs );
699     return pAigNew;
700 }
701 
702 ////////////////////////////////////////////////////////////////////////
703 ///                       END OF FILE                                ///
704 ////////////////////////////////////////////////////////////////////////
705 
706 
707 ABC_NAMESPACE_IMPL_END
708 
709