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