1 /**CFile****************************************************************
2 
3   FileName    [aigDup.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [AIG package.]
8 
9   Synopsis    [AIG duplication (re-strashing).]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - April 28, 2007.]
16 
17   Revision    [$Id: aigDup.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "aig/saig/saig.h"
22 #include "misc/tim/tim.h"
23 
24 ABC_NAMESPACE_IMPL_START
25 
26 
27 ////////////////////////////////////////////////////////////////////////
28 ///                        DECLARATIONS                              ///
29 ////////////////////////////////////////////////////////////////////////
30 
31 ////////////////////////////////////////////////////////////////////////
32 ///                     FUNCTION DEFINITIONS                         ///
33 ////////////////////////////////////////////////////////////////////////
34 
35 /**Function*************************************************************
36 
37   Synopsis    [Duplicates the AIG manager.]
38 
39   Description [Orders nodes as follows: PIs, ANDs, POs.]
40 
41   SideEffects []
42 
43   SeeAlso     []
44 
45 ***********************************************************************/
Aig_ManDupSimple(Aig_Man_t * p)46 Aig_Man_t * Aig_ManDupSimple( Aig_Man_t * p )
47 {
48     Aig_Man_t * pNew;
49     Aig_Obj_t * pObj, * pObjNew = NULL;
50     int i;
51     assert( p->pManTime == NULL );
52     // create the new manager
53     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
54     pNew->pName = Abc_UtilStrsav( p->pName );
55     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
56     pNew->nAsserts = p->nAsserts;
57     pNew->nConstrs = p->nConstrs;
58     pNew->nBarBufs = p->nBarBufs;
59     if ( p->vFlopNums )
60         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
61     // create the PIs
62     Aig_ManCleanData( p );
63     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
64     Aig_ManForEachCi( p, pObj, i )
65     {
66         pObjNew = Aig_ObjCreateCi( pNew );
67         pObjNew->Level = pObj->Level;
68         pObj->pData = pObjNew;
69     }
70     // duplicate internal nodes
71     Aig_ManForEachObj( p, pObj, i )
72         if ( Aig_ObjIsBuf(pObj) )
73         {
74             pObjNew = Aig_ObjChild0Copy(pObj);
75             pObj->pData = pObjNew;
76         }
77         else if ( Aig_ObjIsNode(pObj) )
78         {
79             pObjNew = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
80             pObj->pData = pObjNew;
81         }
82     // add the POs
83     Aig_ManForEachCo( p, pObj, i )
84     {
85         pObjNew = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
86         pObj->pData = pObjNew;
87     }
88     assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
89     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
90     // check the resulting network
91     if ( !Aig_ManCheck(pNew) )
92         printf( "Aig_ManDupSimple(): The check has failed.\n" );
93     return pNew;
94 }
95 
96 /**Function*************************************************************
97 
98   Synopsis    [Derives AIG with hints.]
99 
100   Description []
101 
102   SideEffects []
103 
104   SeeAlso     []
105 
106 ***********************************************************************/
Aig_ManDupSimpleWithHints(Aig_Man_t * p,Vec_Int_t * vHints)107 Aig_Man_t * Aig_ManDupSimpleWithHints( Aig_Man_t * p, Vec_Int_t * vHints )
108 {
109     Aig_Man_t * pNew;
110     Aig_Obj_t * pObj = NULL;
111     int i, Entry;
112     assert( p->nAsserts == 0 || p->nConstrs == 0 );
113     // create the new manager
114     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
115     pNew->pName = Abc_UtilStrsav( p->pName );
116     // create the PIs
117     Aig_ManCleanData( p );
118     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
119     Aig_ManForEachCi( p, pObj, i )
120     {
121         pObj->pData = Aig_ObjCreateCi( pNew );
122         Entry = Vec_IntEntry( vHints, Aig_ObjId(pObj) );
123         if ( Entry == 0 || Entry == 1 )
124             pObj->pData = Aig_NotCond( Aig_ManConst1(pNew), Entry ); // restrict to the complement of constraint!!!
125     }
126     // duplicate internal nodes
127     Aig_ManForEachNode( p, pObj, i )
128     {
129         pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
130         Entry = Vec_IntEntry( vHints, Aig_ObjId(pObj) );
131         if ( Entry == 0 || Entry == 1 )
132             pObj->pData = Aig_NotCond( Aig_ManConst1(pNew), Entry ); // restrict to the complement of constraint!!!
133     }
134     // add the POs
135     Aig_ManForEachCo( p, pObj, i )
136         pObj->pData = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
137     Aig_ManCleanup( pNew );
138     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
139     // check the resulting network
140     if ( !Aig_ManCheck(pNew) )
141         printf( "Llb_ManDeriveAigWithHints(): The check has failed.\n" );
142     return pNew;
143 }
144 
145 
146 /**Function*************************************************************
147 
148   Synopsis    [Duplicates the AIG manager recursively.]
149 
150   Description []
151 
152   SideEffects []
153 
154   SeeAlso     []
155 
156 ***********************************************************************/
Aig_ManDupSimpleDfs_rec(Aig_Man_t * pNew,Aig_Man_t * p,Aig_Obj_t * pObj)157 Aig_Obj_t * Aig_ManDupSimpleDfs_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj )
158 {
159     if ( pObj->pData )
160         return (Aig_Obj_t *)pObj->pData;
161     Aig_ManDupSimpleDfs_rec( pNew, p, Aig_ObjFanin0(pObj) );
162     if ( Aig_ObjIsBuf(pObj) )
163         return (Aig_Obj_t *)(pObj->pData = Aig_ObjChild0Copy(pObj));
164     Aig_ManDupSimpleDfs_rec( pNew, p, Aig_ObjFanin1(pObj) );
165     pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
166     return (Aig_Obj_t *)pObj->pData;
167 }
168 
169 /**Function*************************************************************
170 
171   Synopsis    [Duplicates the AIG manager.]
172 
173   Description [Orders nodes as follows: PIs, ANDs, POs.]
174 
175   SideEffects [This procedure assumes that buffers are not used during
176   HAIG recording. This way, each HAIG node is in one-to-one correspondence
177   with old HAIG node. There is no need to create new nodes, just reassign
178   the pointers. If it were not the case, we would need to create HAIG nodes
179   for each new node duplicated. ]
180 
181   SeeAlso     []
182 
183 ***********************************************************************/
Aig_ManDupSimpleDfs(Aig_Man_t * p)184 Aig_Man_t * Aig_ManDupSimpleDfs( Aig_Man_t * p )
185 {
186     Aig_Man_t * pNew;
187     Aig_Obj_t * pObj, * pObjNew = NULL;
188     int i;
189     assert( p->pManTime == NULL );
190     // create the new manager
191     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
192     pNew->pName = Abc_UtilStrsav( p->pName );
193     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
194     pNew->nAsserts = p->nAsserts;
195     pNew->nConstrs = p->nConstrs;
196     pNew->nBarBufs = p->nBarBufs;
197     if ( p->vFlopNums )
198         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
199     // create the PIs
200     Aig_ManCleanData( p );
201     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
202     Aig_ManForEachCi( p, pObj, i )
203     {
204         pObjNew = Aig_ObjCreateCi( pNew );
205         pObjNew->Level = pObj->Level;
206         pObj->pData = pObjNew;
207     }
208     // duplicate internal nodes
209     Aig_ManForEachObj( p, pObj, i )
210         if ( !Aig_ObjIsCo(pObj) )
211         {
212             Aig_ManDupSimpleDfs_rec( pNew, p, pObj );
213             assert( pObj->Level == ((Aig_Obj_t*)pObj->pData)->Level );
214         }
215     // add the POs
216     Aig_ManForEachCo( p, pObj, i )
217     {
218         pObjNew = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
219         pObj->pData = pObjNew;
220     }
221     assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
222     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
223     // check the resulting network
224     if ( !Aig_ManCheck(pNew) )
225         printf( "Aig_ManDupSimple(): The check has failed.\n" );
226     return pNew;
227 }
228 
229 /**Function*************************************************************
230 
231   Synopsis    [Duplicates part of the AIG manager.]
232 
233   Description [Orders nodes as follows: PIs, ANDs, POs.]
234 
235   SideEffects []
236 
237   SeeAlso     []
238 
239 ***********************************************************************/
Aig_ManDupSimpleDfsPart(Aig_Man_t * p,Vec_Ptr_t * vPis,Vec_Ptr_t * vPos)240 Aig_Man_t * Aig_ManDupSimpleDfsPart( Aig_Man_t * p, Vec_Ptr_t * vPis, Vec_Ptr_t * vPos )
241 {
242     Aig_Man_t * pNew;
243     Aig_Obj_t * pObj, * pObjNew = NULL;
244     int i;
245     // create the new manager
246     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
247     // create the PIs
248     Aig_ManCleanData( p );
249     Aig_ManConst1(p)->pData = Aig_ManConst1( pNew );
250     Vec_PtrForEachEntry( Aig_Obj_t *, vPis, pObj, i )
251         pObj->pData = Aig_ObjCreateCi( pNew );
252     // duplicate internal nodes
253     Vec_PtrForEachEntry( Aig_Obj_t *, vPos, pObj, i )
254     {
255         pObjNew = Aig_ManDupSimpleDfs_rec( pNew, p, Aig_ObjFanin0(pObj) );
256         pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObj) );
257         Aig_ObjCreateCo( pNew, pObjNew );
258     }
259     Aig_ManSetRegNum( pNew, 0 );
260     // check the resulting network
261     if ( !Aig_ManCheck(pNew) )
262         printf( "Aig_ManDupSimple(): The check has failed.\n" );
263     return pNew;
264 }
265 
266 /**Function*************************************************************
267 
268   Synopsis    [Duplicates the AIG manager.]
269 
270   Description [Assumes topological ordering of the nodes.]
271 
272   SideEffects []
273 
274   SeeAlso     []
275 
276 ***********************************************************************/
Aig_ManDupOrdered(Aig_Man_t * p)277 Aig_Man_t * Aig_ManDupOrdered( Aig_Man_t * p )
278 {
279     Aig_Man_t * pNew;
280     Aig_Obj_t * pObj, * pObjNew = NULL;
281     int i, nNodes;
282     // create the new manager
283     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
284     pNew->pName = Abc_UtilStrsav( p->pName );
285     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
286     pNew->nAsserts = p->nAsserts;
287     pNew->nConstrs = p->nConstrs;
288     pNew->nBarBufs = p->nBarBufs;
289     if ( p->vFlopNums )
290         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
291     // create the PIs
292     Aig_ManCleanData( p );
293     // duplicate internal nodes
294     Aig_ManForEachObj( p, pObj, i )
295     {
296         if ( Aig_ObjIsBuf(pObj) )
297         {
298             pObjNew = Aig_ObjChild0Copy(pObj);
299         }
300         else if ( Aig_ObjIsNode(pObj) )
301         {
302             pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) );
303         }
304         else if ( Aig_ObjIsCi(pObj) )
305         {
306             pObjNew = Aig_ObjCreateCi( pNew );
307             pObjNew->Level = pObj->Level;
308         }
309         else if ( Aig_ObjIsCo(pObj) )
310         {
311             pObjNew = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
312         }
313         else if ( Aig_ObjIsConst1(pObj) )
314         {
315             pObjNew = Aig_ManConst1(pNew);
316         }
317         else
318             assert( 0 );
319         pObj->pData = pObjNew;
320     }
321     assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
322     if ( (nNodes = Aig_ManCleanup( pNew )) )
323         printf( "Aig_ManDupOrdered(): Cleanup after AIG duplication removed %d nodes.\n", nNodes );
324     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
325     // duplicate the timing manager
326     if ( p->pManTime )
327         pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 );
328     // check the resulting network
329     if ( !Aig_ManCheck(pNew) )
330         printf( "Aig_ManDupOrdered(): The check has failed.\n" );
331     return pNew;
332 }
333 
334 /**Function*************************************************************
335 
336   Synopsis    [Duplicates the AIG manager.]
337 
338   Description [Orders nodes as follows: PIs, ANDs, POs.]
339 
340   SideEffects []
341 
342   SeeAlso     []
343 
344 ***********************************************************************/
Aig_ManDupCof(Aig_Man_t * p,int iInput,int Value)345 Aig_Man_t * Aig_ManDupCof( Aig_Man_t * p, int iInput, int Value )
346 {
347     Aig_Man_t * pNew;
348     Aig_Obj_t * pObj, * pObjNew = NULL;
349     int i;
350     assert( p->pManTime == NULL );
351     // create the new manager
352     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
353     pNew->pName = Abc_UtilStrsav( p->pName );
354     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
355     pNew->nAsserts = p->nAsserts;
356     pNew->nConstrs = p->nConstrs;
357     pNew->nBarBufs = p->nBarBufs;
358     if ( p->vFlopNums )
359         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
360     // create the PIs
361     Aig_ManCleanData( p );
362     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
363     Aig_ManForEachCi( p, pObj, i )
364     {
365         if ( i == iInput )
366             pObjNew = Value ? Aig_ManConst1(pNew) : Aig_ManConst0(pNew);
367         else
368         {
369             pObjNew = Aig_ObjCreateCi( pNew );
370             pObjNew->Level = pObj->Level;
371         }
372         pObj->pData = pObjNew;
373     }
374     // duplicate internal nodes
375     Aig_ManForEachObj( p, pObj, i )
376         if ( Aig_ObjIsBuf(pObj) )
377         {
378             pObjNew = Aig_ObjChild0Copy(pObj);
379             pObj->pData = pObjNew;
380         }
381         else if ( Aig_ObjIsNode(pObj) )
382         {
383             pObjNew = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
384             pObj->pData = pObjNew;
385         }
386     // add the POs
387     Aig_ManForEachCo( p, pObj, i )
388     {
389         pObjNew = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
390         pObj->pData = pObjNew;
391     }
392 //    assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
393     Aig_ManCleanup( pNew );
394     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
395     // check the resulting network
396     if ( !Aig_ManCheck(pNew) )
397         printf( "Aig_ManDupSimple(): The check has failed.\n" );
398     return pNew;
399 }
400 
401 
402 /**Function*************************************************************
403 
404   Synopsis    [Duplicates the AIG manager.]
405 
406   Description [Assumes topological ordering of the nodes.]
407 
408   SideEffects []
409 
410   SeeAlso     []
411 
412 ***********************************************************************/
Aig_ManDupTrim(Aig_Man_t * p)413 Aig_Man_t * Aig_ManDupTrim( Aig_Man_t * p )
414 {
415     Aig_Man_t * pNew;
416     Aig_Obj_t * pObj, * pObjNew = NULL;
417     int i, nNodes;
418     // create the new manager
419     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
420     pNew->pName = Abc_UtilStrsav( p->pName );
421     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
422     pNew->nConstrs = p->nConstrs;
423     pNew->nBarBufs = p->nBarBufs;
424     // create the PIs
425     Aig_ManCleanData( p );
426     // duplicate internal nodes
427     Aig_ManForEachObj( p, pObj, i )
428     {
429         if ( Aig_ObjIsNode(pObj) )
430             pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) );
431         else if ( Aig_ObjIsCi(pObj) )
432             pObjNew = (Aig_ObjRefs(pObj) > 0 || Saig_ObjIsLo(p, pObj)) ? Aig_ObjCreateCi(pNew) : NULL;
433         else if ( Aig_ObjIsCo(pObj) )
434             pObjNew = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
435         else if ( Aig_ObjIsConst1(pObj) )
436             pObjNew = Aig_ManConst1(pNew);
437         else
438             assert( 0 );
439         pObj->pData = pObjNew;
440     }
441     assert( Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
442     if ( (nNodes = Aig_ManCleanup( pNew )) )
443         printf( "Aig_ManDupTrim(): Cleanup after AIG duplication removed %d nodes.\n", nNodes );
444     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
445     // check the resulting network
446     if ( !Aig_ManCheck(pNew) )
447         printf( "Aig_ManDupTrim(): The check has failed.\n" );
448     return pNew;
449 }
450 
451 /**Function*************************************************************
452 
453   Synopsis    [Duplicates the AIG manager to have EXOR gates.]
454 
455   Description [Assumes topological ordering of the nodes.]
456 
457   SideEffects []
458 
459   SeeAlso     []
460 
461 ***********************************************************************/
Aig_ManDupExor(Aig_Man_t * p)462 Aig_Man_t * Aig_ManDupExor( Aig_Man_t * p )
463 {
464     Aig_Man_t * pNew;
465     Aig_Obj_t * pObj, * pObjNew = NULL;
466     int i;
467     // create the new manager
468     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
469     pNew->fCatchExor = 1;
470     pNew->pName = Abc_UtilStrsav( p->pName );
471     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
472     pNew->nAsserts = p->nAsserts;
473     pNew->nConstrs = p->nConstrs;
474     pNew->nBarBufs = p->nBarBufs;
475     if ( p->vFlopNums )
476         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
477     // create the PIs
478     Aig_ManCleanData( p );
479     // duplicate internal nodes
480     Aig_ManForEachObj( p, pObj, i )
481     {
482         if ( Aig_ObjIsBuf(pObj) )
483         {
484             pObjNew = Aig_ObjChild0Copy(pObj);
485         }
486         else if ( Aig_ObjIsNode(pObj) )
487         {
488             pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) );
489         }
490         else if ( Aig_ObjIsCi(pObj) )
491         {
492             pObjNew = Aig_ObjCreateCi( pNew );
493             pObjNew->Level = pObj->Level;
494         }
495         else if ( Aig_ObjIsCo(pObj) )
496         {
497             pObjNew = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
498         }
499         else if ( Aig_ObjIsConst1(pObj) )
500         {
501             pObjNew = Aig_ManConst1(pNew);
502         }
503         else
504             assert( 0 );
505         pObj->pData = pObjNew;
506     }
507     Aig_ManCleanup( pNew );
508     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
509     // duplicate the timing manager
510     if ( p->pManTime )
511         pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 );
512     // check the resulting network
513     if ( !Aig_ManCheck(pNew) )
514         printf( "Aig_ManDupExor(): The check has failed.\n" );
515     return pNew;
516 }
517 
518 /**Function*************************************************************
519 
520   Synopsis    [Duplicates the AIG manager recursively.]
521 
522   Description []
523 
524   SideEffects []
525 
526   SeeAlso     []
527 
528 ***********************************************************************/
Aig_ManDupDfs_rec(Aig_Man_t * pNew,Aig_Man_t * p,Aig_Obj_t * pObj)529 Aig_Obj_t * Aig_ManDupDfs_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj )
530 {
531     Aig_Obj_t * pObjNew, * pEquivNew = NULL;
532     if ( pObj->pData )
533         return (Aig_Obj_t *)pObj->pData;
534     if ( p->pEquivs && Aig_ObjEquiv(p, pObj) )
535         pEquivNew = Aig_ManDupDfs_rec( pNew, p, Aig_ObjEquiv(p, pObj) );
536     Aig_ManDupDfs_rec( pNew, p, Aig_ObjFanin0(pObj) );
537     if ( Aig_ObjIsBuf(pObj) )
538         return (Aig_Obj_t *)(pObj->pData = Aig_ObjChild0Copy(pObj));
539     Aig_ManDupDfs_rec( pNew, p, Aig_ObjFanin1(pObj) );
540     pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) );
541     if ( pEquivNew )
542     {
543         assert( Aig_Regular(pEquivNew)->Id < Aig_Regular(pObjNew)->Id );
544         if ( pNew->pEquivs )
545             pNew->pEquivs[Aig_Regular(pObjNew)->Id] = Aig_Regular(pEquivNew);
546         if ( pNew->pReprs )
547             pNew->pReprs[Aig_Regular(pEquivNew)->Id] = Aig_Regular(pObjNew);
548     }
549     return (Aig_Obj_t *)(pObj->pData = pObjNew);
550 }
551 
552 /**Function*************************************************************
553 
554   Synopsis    [Duplicates the AIG manager.]
555 
556   Description [This duplicator works for AIGs with choices.]
557 
558   SideEffects []
559 
560   SeeAlso     []
561 
562 ***********************************************************************/
Aig_ManDupDfs(Aig_Man_t * p)563 Aig_Man_t * Aig_ManDupDfs( Aig_Man_t * p )
564 {
565     Aig_Man_t * pNew;
566     Aig_Obj_t * pObj, * pObjNew = NULL;
567     int i, nNodes;
568     // create the new manager
569     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
570     pNew->pName = Abc_UtilStrsav( p->pName );
571     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
572     pNew->nAsserts = p->nAsserts;
573     pNew->nConstrs = p->nConstrs;
574     pNew->nBarBufs = p->nBarBufs;
575     if ( p->vFlopNums )
576         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
577     // duplicate representation of choice nodes
578     if ( p->pEquivs )
579         pNew->pEquivs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p) );
580     if ( p->pReprs )
581         pNew->pReprs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p) );
582     // create the PIs
583     Aig_ManCleanData( p );
584     // duplicate internal nodes
585     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
586     Aig_ManForEachObj( p, pObj, i )
587     {
588         if ( Aig_ObjIsCi(pObj) )
589         {
590             pObjNew = Aig_ObjCreateCi( pNew );
591             pObjNew->Level = pObj->Level;
592             pObj->pData = pObjNew;
593         }
594         else if ( Aig_ObjIsCo(pObj) )
595         {
596             Aig_ManDupDfs_rec( pNew, p, Aig_ObjFanin0(pObj) );
597 //            assert( pObj->Level == ((Aig_Obj_t*)pObj->pData)->Level );
598             pObjNew = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
599             pObj->pData = pObjNew;
600         }
601     }
602     assert( p->pEquivs != NULL || Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
603     if ( p->pEquivs == NULL && p->pReprs == NULL && (nNodes = Aig_ManCleanup( pNew )) )
604         printf( "Aig_ManDupDfs(): Cleanup after AIG duplication removed %d nodes.\n", nNodes );
605     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
606     // duplicate the timing manager
607     if ( p->pManTime )
608         pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 );
609     // check the resulting network
610     if ( !Aig_ManCheck(pNew) )
611         printf( "Aig_ManDupDfs(): The check has failed.\n" );
612     return pNew;
613 }
614 
615 /**Function*************************************************************
616 
617   Synopsis    [Duplicates the AIG manager.]
618 
619   Description [This duplicator works for AIGs with choices.]
620 
621   SideEffects []
622 
623   SeeAlso     []
624 
625 ***********************************************************************/
Aig_ManOrderPios(Aig_Man_t * p,Aig_Man_t * pOrder)626 Vec_Ptr_t * Aig_ManOrderPios( Aig_Man_t * p, Aig_Man_t * pOrder )
627 {
628     Vec_Ptr_t * vPios;
629     Aig_Obj_t * pObj = NULL;
630     int i;
631     assert( Aig_ManCiNum(p) == Aig_ManCiNum(pOrder) );
632     assert( Aig_ManCoNum(p) == Aig_ManCoNum(pOrder) );
633     Aig_ManSetCioIds( pOrder );
634     vPios = Vec_PtrAlloc( Aig_ManCiNum(p) + Aig_ManCoNum(p) );
635     Aig_ManForEachObj( pOrder, pObj, i )
636     {
637         if ( Aig_ObjIsCi(pObj) )
638             Vec_PtrPush( vPios, Aig_ManCi(p, Aig_ObjCioId(pObj)) );
639         else if ( Aig_ObjIsCo(pObj) )
640             Vec_PtrPush( vPios, Aig_ManCo(p, Aig_ObjCioId(pObj)) );
641     }
642     Aig_ManCleanCioIds( pOrder );
643     return vPios;
644 }
645 
646 /**Function*************************************************************
647 
648   Synopsis    [Duplicates the AIG manager recursively.]
649 
650   Description []
651 
652   SideEffects []
653 
654   SeeAlso     []
655 
656 ***********************************************************************/
Aig_ManDupDfsGuided_rec(Aig_Man_t * pNew,Aig_Man_t * p,Aig_Obj_t * pObj)657 Aig_Obj_t * Aig_ManDupDfsGuided_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj )
658 {
659     Aig_Obj_t * pObjNew, * pEquivNew = NULL;
660     if ( pObj->pData )
661         return (Aig_Obj_t *)pObj->pData;
662     if ( Aig_ObjIsCi(pObj) )
663         return NULL;
664     if ( p->pEquivs && Aig_ObjEquiv(p, pObj) )
665         pEquivNew = Aig_ManDupDfsGuided_rec( pNew, p, Aig_ObjEquiv(p, pObj) );
666     if ( !Aig_ManDupDfsGuided_rec( pNew, p, Aig_ObjFanin0(pObj) ) )
667         return NULL;
668     if ( Aig_ObjIsBuf(pObj) )
669         return (Aig_Obj_t *)(pObj->pData = Aig_ObjChild0Copy(pObj));
670     if ( !Aig_ManDupDfsGuided_rec( pNew, p, Aig_ObjFanin1(pObj) ) )
671         return NULL;
672     pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) );
673     if ( pEquivNew )
674     {
675         if ( pNew->pEquivs )
676             pNew->pEquivs[Aig_Regular(pObjNew)->Id] = Aig_Regular(pEquivNew);
677         if ( pNew->pReprs )
678             pNew->pReprs[Aig_Regular(pEquivNew)->Id] = Aig_Regular(pObjNew);
679     }
680     return (Aig_Obj_t *)(pObj->pData = pObjNew);
681 }
682 
683 /**Function*************************************************************
684 
685   Synopsis    [Duplicates the AIG manager.]
686 
687   Description [This duplicator works for AIGs with choices.]
688 
689   SideEffects []
690 
691   SeeAlso     []
692 
693 ***********************************************************************/
Aig_ManDupDfsGuided(Aig_Man_t * p,Vec_Ptr_t * vPios)694 Aig_Man_t * Aig_ManDupDfsGuided( Aig_Man_t * p, Vec_Ptr_t * vPios )
695 {
696     Aig_Man_t * pNew;
697     Aig_Obj_t * pObj, * pObjNew = NULL;
698     int i, nNodes;
699     // create the new manager
700     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
701     pNew->pName = Abc_UtilStrsav( p->pName );
702     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
703     pNew->nAsserts = p->nAsserts;
704     pNew->nConstrs = p->nConstrs;
705     pNew->nBarBufs = p->nBarBufs;
706     if ( p->vFlopNums )
707         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
708     // duplicate representation of choice nodes
709     if ( p->pEquivs )
710     {
711         pNew->pEquivs = ABC_ALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p) );
712         memset( pNew->pEquivs, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(p) );
713     }
714     if ( p->pReprs )
715     {
716         pNew->pReprs = ABC_ALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p) );
717         memset( pNew->pReprs, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(p) );
718     }
719     // create the PIs
720     Aig_ManCleanData( p );
721     // duplicate internal nodes
722     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
723     Vec_PtrForEachEntry( Aig_Obj_t *, vPios, pObj, i )
724     {
725         if ( Aig_ObjIsCi(pObj) )
726         {
727             pObjNew = Aig_ObjCreateCi( pNew );
728             pObjNew->Level = pObj->Level;
729             pObj->pData = pObjNew;
730         }
731         else if ( Aig_ObjIsCo(pObj) )
732         {
733             Aig_ManDupDfsGuided_rec( pNew, p, Aig_ObjFanin0(pObj) );
734 //            assert( pObj->Level == ((Aig_Obj_t*)pObj->pData)->Level );
735             pObjNew = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
736             pObj->pData = pObjNew;
737         }
738     }
739 //    assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
740     if ( p->pEquivs == NULL && p->pReprs == NULL && (nNodes = Aig_ManCleanup( pNew )) )
741         printf( "Aig_ManDupDfs(): Cleanup after AIG duplication removed %d nodes.\n", nNodes );
742     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
743     // duplicate the timing manager
744     if ( p->pManTime )
745         pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 );
746     // check the resulting network
747     if ( !Aig_ManCheck(pNew) )
748         printf( "Aig_ManDupDfs(): The check has failed.\n" );
749     return pNew;
750 }
751 
752 /**Function*************************************************************
753 
754   Synopsis    [Duplicates the AIG manager.]
755 
756   Description [This duplicator works for AIGs with choices.]
757 
758   SideEffects []
759 
760   SeeAlso     []
761 
762 ***********************************************************************/
Aig_ManDupLevelized(Aig_Man_t * p)763 Aig_Man_t * Aig_ManDupLevelized( Aig_Man_t * p )
764 {
765     Vec_Vec_t * vLevels;
766     Aig_Man_t * pNew;
767     Aig_Obj_t * pObj, * pObjNew = NULL;
768     int i, k;
769     // create the new manager
770     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
771     pNew->pName = Abc_UtilStrsav( p->pName );
772     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
773     pNew->nAsserts = p->nAsserts;
774     pNew->nConstrs = p->nConstrs;
775     pNew->nBarBufs = p->nBarBufs;
776     if ( p->vFlopNums )
777         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
778     // duplicate representation of choice nodes
779     if ( p->pEquivs )
780     {
781         pNew->pEquivs = ABC_ALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p) );
782         memset( pNew->pEquivs, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(p) );
783     }
784     if ( p->pReprs )
785     {
786         pNew->pReprs = ABC_ALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p) );
787         memset( pNew->pReprs, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(p) );
788     }
789     // create the PIs
790     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
791     Aig_ManForEachCi( p, pObj, i )
792     {
793         pObjNew = Aig_ObjCreateCi( pNew );
794         pObjNew->Level = pObj->Level;
795         pObj->pData = pObjNew;
796     }
797     // duplicate internal nodes
798     vLevels = Aig_ManLevelize( p );
799     Vec_VecForEachEntry( Aig_Obj_t *, vLevels, pObj, i, k )
800     {
801         pObjNew = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) );
802         pObj->pData = pObjNew;
803     }
804     Vec_VecFree( vLevels );
805     // duplicate POs
806     Aig_ManForEachCo( p, pObj, i )
807     {
808         pObjNew = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
809         pObj->pData = pObjNew;
810     }
811     assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
812 //    if ( (nNodes = Aig_ManCleanup( pNew )) )
813 //        printf( "Aig_ManDupLevelized(): Cleanup after AIG duplication removed %d nodes.\n", nNodes );
814     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
815     // duplicate the timing manager
816     if ( p->pManTime )
817         pNew->pManTime = Tim_ManDup( (Tim_Man_t *)p->pManTime, 0 );
818     // check the resulting network
819     if ( !Aig_ManCheck(pNew) )
820         printf( "Aig_ManDupLevelized(): The check has failed.\n" );
821     return pNew;
822 }
823 
824 /**Function*************************************************************
825 
826   Synopsis    [Duplicates the AIG manager.]
827 
828   Description [Assumes topological ordering of nodes.]
829 
830   SideEffects []
831 
832   SeeAlso     []
833 
834 ***********************************************************************/
Aig_ManDupWithoutPos(Aig_Man_t * p)835 Aig_Man_t * Aig_ManDupWithoutPos( Aig_Man_t * p )
836 {
837     Aig_Man_t * pNew;
838     Aig_Obj_t * pObj = NULL;
839     int i;
840     // create the new manager
841     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
842     pNew->pName = Abc_UtilStrsav( p->pName );
843     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
844     // create the PIs
845     Aig_ManCleanData( p );
846     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
847     Aig_ManForEachCi( p, pObj, i )
848         pObj->pData = Aig_ObjCreateCi( pNew );
849     // duplicate internal nodes
850     Aig_ManForEachObj( p, pObj, i )
851     {
852         assert( !Aig_ObjIsBuf(pObj) );
853         if ( Aig_ObjIsNode(pObj) )
854             pObj->pData = Aig_Oper( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj), Aig_ObjType(pObj) );
855     }
856     assert( Aig_ManBufNum(p) != 0 || Aig_ManNodeNum(p) == Aig_ManNodeNum(pNew) );
857     return pNew;
858 }
859 
860 /**Function*************************************************************
861 
862   Synopsis    [Duplicates the AIG manager.]
863 
864   Description [Assumes topological ordering of nodes.]
865 
866   SideEffects []
867 
868   SeeAlso     []
869 
870 ***********************************************************************/
Aig_ManDupFlopsOnly(Aig_Man_t * p)871 Aig_Man_t * Aig_ManDupFlopsOnly( Aig_Man_t * p )
872 {
873     Aig_Man_t * pNew;
874     Aig_Obj_t * pObj = NULL;
875     int i;
876     pNew = Aig_ManDupWithoutPos( p );
877     Saig_ManForEachLi( p, pObj, i )
878         pObj->pData = Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
879     Aig_ManCleanup( pNew );
880     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
881     if ( !Aig_ManCheck(pNew) )
882         printf( "Aig_ManDupFlopsOnly(): The check has failed.\n" );
883     return pNew;
884 
885 }
886 
887 
888 /**Function*************************************************************
889 
890   Synopsis    [Returns representatives of fanin in approapriate polarity.]
891 
892   Description []
893 
894   SideEffects []
895 
896   SeeAlso     []
897 
898 ***********************************************************************/
Aig_ObjGetRepres(Aig_Man_t * p,Aig_Obj_t * pObj)899 static inline Aig_Obj_t * Aig_ObjGetRepres( Aig_Man_t * p, Aig_Obj_t * pObj )
900 {
901     Aig_Obj_t * pRepr;
902     if ( (pRepr = Aig_ObjRepr(p, pObj)) )
903         return Aig_NotCond( (Aig_Obj_t *)pRepr->pData, pObj->fPhase ^ pRepr->fPhase );
904     return (Aig_Obj_t *)pObj->pData;
905 }
Aig_ObjChild0Repres(Aig_Man_t * p,Aig_Obj_t * pObj)906 static inline Aig_Obj_t * Aig_ObjChild0Repres( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_NotCond( Aig_ObjGetRepres(p, Aig_ObjFanin0(pObj)), Aig_ObjFaninC0(pObj) ); }
Aig_ObjChild1Repres(Aig_Man_t * p,Aig_Obj_t * pObj)907 static inline Aig_Obj_t * Aig_ObjChild1Repres( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_NotCond( Aig_ObjGetRepres(p, Aig_ObjFanin1(pObj)), Aig_ObjFaninC1(pObj) ); }
908 
909 /**Function*************************************************************
910 
911   Synopsis    [Duplicates AIG while substituting representatives.]
912 
913   Description []
914 
915   SideEffects []
916 
917   SeeAlso     []
918 
919 ***********************************************************************/
Aig_ManDupRepres(Aig_Man_t * p)920 Aig_Man_t * Aig_ManDupRepres( Aig_Man_t * p )
921 {
922     Aig_Man_t * pNew;
923     Aig_Obj_t * pObj = NULL;
924     int i;
925     // start the HOP package
926     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
927     pNew->pName = Abc_UtilStrsav( p->pName );
928     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
929     pNew->nConstrs = p->nConstrs;
930     pNew->nBarBufs = p->nBarBufs;
931     if ( p->vFlopNums )
932         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
933     // map the const and primary inputs
934     Aig_ManCleanData( p );
935     Aig_ManForEachObj( p, pObj, i )
936     {
937         if ( Aig_ObjIsNode(pObj) )
938             pObj->pData = Aig_And( pNew, Aig_ObjChild0Repres(p, pObj), Aig_ObjChild1Repres(p, pObj) );
939         else if ( Aig_ObjIsCi(pObj) )
940         {
941             pObj->pData = Aig_ObjCreateCi(pNew);
942             pObj->pData = Aig_ObjGetRepres( p, pObj );
943         }
944         else if ( Aig_ObjIsCo(pObj) )
945             pObj->pData = Aig_ObjCreateCo( pNew, Aig_ObjChild0Repres(p, pObj) );
946         else if ( Aig_ObjIsConst1(pObj) )
947             pObj->pData = Aig_ManConst1(pNew);
948         else
949             assert( 0 );
950     }
951     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
952     // check the new manager
953     if ( !Aig_ManCheck(pNew) )
954         printf( "Aig_ManDupRepres: Check has failed.\n" );
955     return pNew;
956 }
957 
958 /**Function*************************************************************
959 
960   Synopsis    [Duplicates the AIG manager recursively.]
961 
962   Description []
963 
964   SideEffects []
965 
966   SeeAlso     []
967 
968 ***********************************************************************/
Aig_ManDupRepres_rec(Aig_Man_t * pNew,Aig_Man_t * p,Aig_Obj_t * pObj)969 Aig_Obj_t * Aig_ManDupRepres_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj )
970 {
971     Aig_Obj_t * pRepr;
972     if ( pObj->pData )
973         return (Aig_Obj_t *)pObj->pData;
974     if ( (pRepr = Aig_ObjRepr(p, pObj)) )
975     {
976         Aig_ManDupRepres_rec( pNew, p, pRepr );
977         return (Aig_Obj_t *)(pObj->pData = Aig_NotCond( (Aig_Obj_t *)pRepr->pData, pRepr->fPhase ^ pObj->fPhase ));
978     }
979     Aig_ManDupRepres_rec( pNew, p, Aig_ObjFanin0(pObj) );
980     Aig_ManDupRepres_rec( pNew, p, Aig_ObjFanin1(pObj) );
981     return (Aig_Obj_t *)(pObj->pData = Aig_And( pNew, Aig_ObjChild0Repres(p, pObj), Aig_ObjChild1Repres(p, pObj) ));
982 }
983 
984 /**Function*************************************************************
985 
986   Synopsis    [Duplicates AIG while substituting representatives.]
987 
988   Description []
989 
990   SideEffects []
991 
992   SeeAlso     []
993 
994 ***********************************************************************/
Aig_ManDupRepresDfs(Aig_Man_t * p)995 Aig_Man_t * Aig_ManDupRepresDfs( Aig_Man_t * p )
996 {
997     Aig_Man_t * pNew;
998     Aig_Obj_t * pObj = NULL;
999     int i;
1000     // start the HOP package
1001     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
1002     pNew->pName = Abc_UtilStrsav( p->pName );
1003     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
1004     pNew->nConstrs = p->nConstrs;
1005     pNew->nBarBufs = p->nBarBufs;
1006     if ( p->vFlopNums )
1007         pNew->vFlopNums = Vec_IntDup( p->vFlopNums );
1008     // map the const and primary inputs
1009     Aig_ManCleanData( p );
1010     Aig_ManForEachObj( p, pObj, i )
1011     {
1012         if ( Aig_ObjIsNode(pObj) )
1013             continue;
1014         if ( Aig_ObjIsCi(pObj) )
1015             pObj->pData = Aig_ObjCreateCi(pNew);
1016         else if ( Aig_ObjIsCo(pObj) )
1017         {
1018             Aig_ManDupRepres_rec( pNew, p, Aig_ObjFanin0(pObj) );
1019             pObj->pData = Aig_ObjCreateCo( pNew, Aig_ObjChild0Repres(p, pObj) );
1020         }
1021         else if ( Aig_ObjIsConst1(pObj) )
1022             pObj->pData = Aig_ManConst1(pNew);
1023         else
1024             assert( 0 );
1025     }
1026     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
1027     // check the new manager
1028     if ( !Aig_ManCheck(pNew) )
1029         printf( "Aig_ManDupRepresDfs: Check has failed.\n" );
1030     return pNew;
1031 }
1032 
1033 /**Function*************************************************************
1034 
1035   Synopsis    [Creates the miter of the two AIG managers.]
1036 
1037   Description [Oper is the operation to perform on the outputs of the miter.
1038   Oper == 0 is XOR
1039   Oper == 1 is complemented implication (p1 => p2)
1040   Oper == 2 is OR
1041   Oper == 3 is AND
1042   ]
1043 
1044   SideEffects []
1045 
1046   SeeAlso     []
1047 
1048 ***********************************************************************/
Aig_ManCreateMiter(Aig_Man_t * p1,Aig_Man_t * p2,int Oper)1049 Aig_Man_t * Aig_ManCreateMiter( Aig_Man_t * p1, Aig_Man_t * p2, int Oper )
1050 {
1051     Aig_Man_t * pNew;
1052     Aig_Obj_t * pObj = NULL;
1053     int i;
1054     assert( Aig_ManRegNum(p1) == 0 );
1055     assert( Aig_ManRegNum(p2) == 0 );
1056     assert( Aig_ManCoNum(p1) == 1 );
1057     assert( Aig_ManCoNum(p2) == 1 );
1058     assert( Aig_ManCiNum(p1) == Aig_ManCiNum(p2) );
1059     pNew = Aig_ManStart( Aig_ManObjNumMax(p1) + Aig_ManObjNumMax(p2) );
1060     // add first AIG
1061     Aig_ManConst1(p1)->pData = Aig_ManConst1(pNew);
1062     Aig_ManForEachCi( p1, pObj, i )
1063         pObj->pData = Aig_ObjCreateCi( pNew );
1064     Aig_ManForEachNode( p1, pObj, i )
1065         pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
1066     // add second AIG
1067     Aig_ManConst1(p2)->pData = Aig_ManConst1(pNew);
1068     Aig_ManForEachCi( p2, pObj, i )
1069         pObj->pData = Aig_ManCi( pNew, i );
1070     Aig_ManForEachNode( p2, pObj, i )
1071         pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
1072     // add the output
1073     if ( Oper == 0 ) // XOR
1074         pObj = Aig_Exor( pNew, Aig_ObjChild0Copy(Aig_ManCo(p1,0)), Aig_ObjChild0Copy(Aig_ManCo(p2,0)) );
1075     else if ( Oper == 1 ) // implication is PO(p1) -> PO(p2)  ...  complement is PO(p1) & !PO(p2)
1076         pObj = Aig_And( pNew, Aig_ObjChild0Copy(Aig_ManCo(p1,0)), Aig_Not(Aig_ObjChild0Copy(Aig_ManCo(p2,0))) );
1077     else if ( Oper == 2 ) // OR
1078         pObj = Aig_Or( pNew, Aig_ObjChild0Copy(Aig_ManCo(p1,0)), Aig_ObjChild0Copy(Aig_ManCo(p2,0)) );
1079     else if ( Oper == 3 ) // AND
1080         pObj = Aig_And( pNew, Aig_ObjChild0Copy(Aig_ManCo(p1,0)), Aig_ObjChild0Copy(Aig_ManCo(p2,0)) );
1081     else
1082         assert( 0 );
1083     Aig_ObjCreateCo( pNew, pObj );
1084     Aig_ManCleanup( pNew );
1085     return pNew;
1086 }
1087 
1088 /**Function*************************************************************
1089 
1090   Synopsis    [Duplicates AIG with only one primary output.]
1091 
1092   Description []
1093 
1094   SideEffects []
1095 
1096   SeeAlso     []
1097 
1098 ***********************************************************************/
Aig_ManDupOrpos(Aig_Man_t * p,int fAddRegs)1099 Aig_Man_t * Aig_ManDupOrpos( Aig_Man_t * p, int fAddRegs )
1100 {
1101     Aig_Man_t * pNew;
1102     Aig_Obj_t * pObj, * pMiter;
1103     int i;
1104     assert( Aig_ManRegNum(p) > 0 );
1105     if ( p->nConstrs > 0 )
1106     {
1107         printf( "The AIG manager should have no constraints.\n" );
1108         return NULL;
1109     }
1110     // create the new manager
1111     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
1112     pNew->pName = Abc_UtilStrsav( p->pName );
1113     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
1114     // create the PIs
1115     Aig_ManCleanData( p );
1116     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
1117     Aig_ManForEachCi( p, pObj, i )
1118         pObj->pData = Aig_ObjCreateCi( pNew );
1119     // set registers
1120     pNew->nRegs    = fAddRegs? p->nRegs : 0;
1121     pNew->nTruePis = fAddRegs? p->nTruePis : p->nTruePis + p->nRegs;
1122     pNew->nTruePos = 1;
1123     // duplicate internal nodes
1124     Aig_ManForEachNode( p, pObj, i )
1125         pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
1126     // create the PO
1127     pMiter = Aig_ManConst0(pNew);
1128     Aig_ManForEachPoSeq( p, pObj, i )
1129         pMiter = Aig_Or( pNew, pMiter, Aig_ObjChild0Copy(pObj) );
1130     Aig_ObjCreateCo( pNew, pMiter );
1131     // create register inputs with MUXes
1132     if ( fAddRegs )
1133     {
1134         Aig_ManForEachLiSeq( p, pObj, i )
1135             Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
1136     }
1137     Aig_ManCleanup( pNew );
1138     return pNew;
1139 }
1140 
1141 /**Function*************************************************************
1142 
1143   Synopsis    [Duplicates AIG with only one primary output.]
1144 
1145   Description []
1146 
1147   SideEffects []
1148 
1149   SeeAlso     []
1150 
1151 ***********************************************************************/
Aig_ManDupOneOutput(Aig_Man_t * p,int iPoNum,int fAddRegs)1152 Aig_Man_t * Aig_ManDupOneOutput( Aig_Man_t * p, int iPoNum, int fAddRegs )
1153 {
1154     Aig_Man_t * pNew;
1155     Aig_Obj_t * pObj = NULL;
1156     int i;
1157     assert( Aig_ManRegNum(p) > 0 );
1158     assert( iPoNum < Aig_ManCoNum(p)-Aig_ManRegNum(p) );
1159     // create the new manager
1160     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
1161     pNew->pName = Abc_UtilStrsav( p->pName );
1162     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
1163     // create the PIs
1164     Aig_ManCleanData( p );
1165     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
1166     Aig_ManForEachCi( p, pObj, i )
1167         pObj->pData = Aig_ObjCreateCi( pNew );
1168     // set registers
1169     pNew->nRegs    = fAddRegs? p->nRegs : 0;
1170     pNew->nTruePis = fAddRegs? p->nTruePis : p->nTruePis + p->nRegs;
1171     pNew->nTruePos = 1;
1172     // duplicate internal nodes
1173     Aig_ManForEachNode( p, pObj, i )
1174         pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
1175     // create the PO
1176     pObj = Aig_ManCo( p, iPoNum );
1177     Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
1178     // create register inputs with MUXes
1179     if ( fAddRegs )
1180     {
1181         Aig_ManForEachLiSeq( p, pObj, i )
1182             Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
1183     }
1184     Aig_ManCleanup( pNew );
1185     return pNew;
1186 }
1187 
1188 /**Function*************************************************************
1189 
1190   Synopsis    [Duplicates AIG with only one primary output.]
1191 
1192   Description []
1193 
1194   SideEffects []
1195 
1196   SeeAlso     []
1197 
1198 ***********************************************************************/
Aig_ManDupUnsolvedOutputs(Aig_Man_t * p,int fAddRegs)1199 Aig_Man_t * Aig_ManDupUnsolvedOutputs( Aig_Man_t * p, int fAddRegs )
1200 {
1201     Aig_Man_t * pNew;
1202     Aig_Obj_t * pObj = NULL;
1203     int i, nOuts = 0;
1204     assert( Aig_ManRegNum(p) > 0 );
1205     if ( p->nConstrs > 0 )
1206     {
1207         printf( "The AIG manager should have no constraints.\n" );
1208         return NULL;
1209     }
1210     // create the new manager
1211     pNew = Aig_ManStart( Aig_ManObjNumMax(p) );
1212     pNew->pName = Abc_UtilStrsav( p->pName );
1213     pNew->pSpec = Abc_UtilStrsav( p->pSpec );
1214     // create the PIs
1215     Aig_ManCleanData( p );
1216     Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
1217     Aig_ManForEachCi( p, pObj, i )
1218         pObj->pData = Aig_ObjCreateCi( pNew );
1219     // create the POs
1220     nOuts = 0;
1221     Aig_ManForEachPoSeq( p, pObj, i )
1222         nOuts += ( Aig_ObjFanin0(pObj) != Aig_ManConst1(p) );
1223     // set registers
1224     pNew->nRegs    = fAddRegs? p->nRegs : 0;
1225     pNew->nTruePis = fAddRegs? p->nTruePis : p->nTruePis + p->nRegs;
1226     pNew->nTruePos = nOuts;
1227     // duplicate internal nodes
1228     Aig_ManForEachNode( p, pObj, i )
1229         pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
1230     // create the PO
1231     Aig_ManForEachPoSeq( p, pObj, i )
1232         if ( Aig_ObjFanin0(pObj) != Aig_ManConst1(p) )
1233             Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
1234     // create register inputs with MUXes
1235     if ( fAddRegs )
1236     {
1237         Aig_ManForEachLiSeq( p, pObj, i )
1238             Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
1239     }
1240     Aig_ManCleanup( pNew );
1241     return pNew;
1242 }
1243 
1244 /**Function*************************************************************
1245 
1246   Synopsis    [Duplicates AIG with only one primary output.]
1247 
1248   Description []
1249 
1250   SideEffects []
1251 
1252   SeeAlso     []
1253 
1254 ***********************************************************************/
Aig_ManDupArray(Vec_Ptr_t * vArray)1255 Aig_Man_t * Aig_ManDupArray( Vec_Ptr_t * vArray )
1256 {
1257     Aig_Man_t * p, * pNew;
1258     Aig_Obj_t * pObj = NULL;
1259     int i, k;
1260     if ( Vec_PtrSize(vArray) == 0 )
1261         return NULL;
1262     p = (Aig_Man_t *)Vec_PtrEntry( vArray, 0 );
1263     Vec_PtrForEachEntry( Aig_Man_t *, vArray, pNew, k )
1264     {
1265         assert( Aig_ManRegNum(pNew) == 0 );
1266         assert( Aig_ManCiNum(pNew) == Aig_ManCiNum(p) );
1267     }
1268     // create the new manager
1269     pNew = Aig_ManStart( 10000 );
1270     pNew->pName = Abc_UtilStrsav( p->pName );
1271     Aig_ManForEachCi( p, pObj, i )
1272         Aig_ObjCreateCi(pNew);
1273     // create the PIs
1274     Vec_PtrForEachEntry( Aig_Man_t *, vArray, p, k )
1275     {
1276         Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
1277         Aig_ManForEachCi( p, pObj, i )
1278             pObj->pData = Aig_ManCi( pNew, i );
1279         Aig_ManForEachNode( p, pObj, i )
1280             pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
1281         Aig_ManForEachCo( p, pObj, i )
1282             Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
1283     }
1284     Aig_ManSetRegNum( pNew, Aig_ManRegNum(p) );
1285     // check the resulting network
1286     if ( !Aig_ManCheck(pNew) )
1287         printf( "Aig_ManDupSimple(): The check has failed.\n" );
1288     return pNew;
1289 }
1290 
1291 /**Function*************************************************************
1292 
1293   Synopsis    [Duplicates AIG with only one primary output.]
1294 
1295   Description []
1296 
1297   SideEffects []
1298 
1299   SeeAlso     []
1300 
1301 ***********************************************************************/
Aig_ManDupNodes(Aig_Man_t * pMan,Vec_Ptr_t * vArray)1302 Aig_Man_t * Aig_ManDupNodes( Aig_Man_t * pMan, Vec_Ptr_t * vArray )
1303 {
1304     Aig_Man_t * pNew;
1305     Vec_Ptr_t * vObjs;
1306     Aig_Obj_t * pObj = NULL;
1307     int i;
1308     if ( Vec_PtrSize(vArray) == 0 )
1309         return NULL;
1310     vObjs = Aig_ManDfsNodes( pMan, (Aig_Obj_t **)Vec_PtrArray(vArray), Vec_PtrSize(vArray) );
1311     // create the new manager
1312     pNew = Aig_ManStart( 10000 );
1313     pNew->pName = Abc_UtilStrsav( pMan->pName );
1314     Aig_ManConst1(pMan)->pData = Aig_ManConst1(pNew);
1315     Vec_PtrForEachEntry( Aig_Obj_t *, vObjs, pObj, i )
1316         if ( Aig_ObjIsCi(pObj) )
1317             pObj->pData = Aig_ObjCreateCi(pNew);
1318     Vec_PtrForEachEntry( Aig_Obj_t *, vObjs, pObj, i )
1319         if ( Aig_ObjIsNode(pObj) )
1320             pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
1321     Vec_PtrForEachEntry( Aig_Obj_t *, vArray, pObj, i )
1322             Aig_ObjCreateCo( pNew, (Aig_Obj_t *)pObj->pData );
1323     Aig_ManSetRegNum( pNew, 0 );
1324     Vec_PtrFree( vObjs );
1325     return pNew;
1326 }
1327 
1328 
1329 ////////////////////////////////////////////////////////////////////////
1330 ///                       END OF FILE                                ///
1331 ////////////////////////////////////////////////////////////////////////
1332 
1333 
1334 ABC_NAMESPACE_IMPL_END
1335 
1336