1 /**CFile****************************************************************
2 
3   FileName    [abcNtk.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Network and node package.]
8 
9   Synopsis    [Network creation/duplication/deletion procedures.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: abcNtk.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "abc.h"
22 #include "abcInt.h"
23 #include "base/main/main.h"
24 #include "map/mio/mio.h"
25 #include "aig/gia/gia.h"
26 
27 #ifdef ABC_USE_CUDD
28 #include "bdd/extrab/extraBdd.h"
29 #endif
30 
31 ABC_NAMESPACE_IMPL_START
32 
33 
34 ////////////////////////////////////////////////////////////////////////
35 ///                        DECLARATIONS                              ///
36 ////////////////////////////////////////////////////////////////////////
37 
38 ////////////////////////////////////////////////////////////////////////
39 ///                     FUNCTION DEFINITIONS                         ///
40 ////////////////////////////////////////////////////////////////////////
41 
42 /**Function*************************************************************
43 
44   Synopsis    [Creates a new Ntk.]
45 
46   Description []
47 
48   SideEffects []
49 
50   SeeAlso     []
51 
52 ***********************************************************************/
Abc_NtkAlloc(Abc_NtkType_t Type,Abc_NtkFunc_t Func,int fUseMemMan)53 Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan )
54 {
55     Abc_Ntk_t * pNtk;
56     pNtk = ABC_ALLOC( Abc_Ntk_t, 1 );
57     memset( pNtk, 0, sizeof(Abc_Ntk_t) );
58     pNtk->ntkType     = Type;
59     pNtk->ntkFunc     = Func;
60     // start the object storage
61     pNtk->vObjs       = Vec_PtrAlloc( 100 );
62     pNtk->vPios       = Vec_PtrAlloc( 100 );
63     pNtk->vPis        = Vec_PtrAlloc( 100 );
64     pNtk->vPos        = Vec_PtrAlloc( 100 );
65     pNtk->vCis        = Vec_PtrAlloc( 100 );
66     pNtk->vCos        = Vec_PtrAlloc( 100 );
67     pNtk->vBoxes      = Vec_PtrAlloc( 100 );
68     pNtk->vLtlProperties = Vec_PtrAlloc( 100 );
69     // start the memory managers
70     pNtk->pMmObj      = fUseMemMan? Mem_FixedStart( sizeof(Abc_Obj_t) ) : NULL;
71     pNtk->pMmStep     = fUseMemMan? Mem_StepStart( ABC_NUM_STEPS ) : NULL;
72     // get ready to assign the first Obj ID
73     pNtk->nTravIds    = 1;
74     // start the functionality manager
75     if ( !Abc_NtkIsStrash(pNtk) )
76         Vec_PtrPush( pNtk->vObjs, NULL );
77     if ( Abc_NtkIsStrash(pNtk) )
78         pNtk->pManFunc = Abc_AigAlloc( pNtk );
79     else if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) )
80         pNtk->pManFunc = Mem_FlexStart();
81 #ifdef ABC_USE_CUDD
82     else if ( Abc_NtkHasBdd(pNtk) )
83         pNtk->pManFunc = Cudd_Init( 20, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
84 #endif
85     else if ( Abc_NtkHasAig(pNtk) )
86         pNtk->pManFunc = Hop_ManStart();
87     else if ( Abc_NtkHasMapping(pNtk) )
88         pNtk->pManFunc = Abc_FrameReadLibGen();
89     else if ( !Abc_NtkHasBlackbox(pNtk) )
90         assert( 0 );
91     // name manager
92     pNtk->pManName = Nm_ManCreate( 200 );
93     // attribute manager
94     pNtk->vAttrs = Vec_PtrStart( VEC_ATTR_TOTAL_NUM );
95     // estimated AndGateDelay
96     pNtk->AndGateDelay = 0.0;
97     return pNtk;
98 }
99 
100 /**Function*************************************************************
101 
102   Synopsis    [Starts a new network using existing network as a model.]
103 
104   Description []
105 
106   SideEffects []
107 
108   SeeAlso     []
109 
110 ***********************************************************************/
Abc_NtkStartFrom(Abc_Ntk_t * pNtk,Abc_NtkType_t Type,Abc_NtkFunc_t Func)111 Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func )
112 {
113     Abc_Ntk_t * pNtkNew;
114     Abc_Obj_t * pObj;
115     int fCopyNames, i;
116     if ( pNtk == NULL )
117         return NULL;
118     // decide whether to copy the names
119     fCopyNames = ( Type != ABC_NTK_NETLIST );
120     // start the network
121     pNtkNew = Abc_NtkAlloc( Type, Func, 1 );
122     pNtkNew->nConstrs   = pNtk->nConstrs;
123     pNtkNew->nBarBufs   = pNtk->nBarBufs;
124     // duplicate the name and the spec
125     pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
126     pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
127     // clean the node copy fields
128     Abc_NtkCleanCopy( pNtk );
129     // map the constant nodes
130     if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) )
131         Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
132     // clone CIs/CIs/boxes
133     Abc_NtkForEachPi( pNtk, pObj, i )
134         Abc_NtkDupObj( pNtkNew, pObj, fCopyNames );
135     Abc_NtkForEachPo( pNtk, pObj, i )
136         Abc_NtkDupObj( pNtkNew, pObj, fCopyNames );
137     Abc_NtkForEachBox( pNtk, pObj, i )
138         Abc_NtkDupBox( pNtkNew, pObj, fCopyNames );
139     // transfer logic level
140     Abc_NtkForEachCi( pNtk, pObj, i )
141         pObj->pCopy->Level = pObj->Level;
142     // transfer the names
143 //    Abc_NtkTrasferNames( pNtk, pNtkNew );
144     Abc_ManTimeDup( pNtk, pNtkNew );
145     if ( pNtk->vOnehots )
146         pNtkNew->vOnehots = (Vec_Ptr_t *)Vec_VecDupInt( (Vec_Vec_t *)pNtk->vOnehots );
147     if ( pNtk->pSeqModel )
148         pNtkNew->pSeqModel = Abc_CexDup( pNtk->pSeqModel, Abc_NtkLatchNum(pNtk) );
149     if ( pNtk->vObjPerm )
150         pNtkNew->vObjPerm = Vec_IntDup( pNtk->vObjPerm );
151     pNtkNew->AndGateDelay = pNtk->AndGateDelay;
152     if ( pNtkNew->pManTime && Abc_FrameReadLibGen() && pNtkNew->AndGateDelay == 0.0 )
153         pNtkNew->AndGateDelay = Mio_LibraryReadDelayAigNode((Mio_Library_t *)Abc_FrameReadLibGen());
154     // initialize logic level of the CIs
155     if ( pNtk->AndGateDelay != 0.0 && pNtk->pManTime != NULL && pNtk->ntkType != ABC_NTK_STRASH && Type == ABC_NTK_STRASH )
156     {
157         Abc_NtkForEachCi( pNtk, pObj, i )
158             pObj->pCopy->Level = (int)(Abc_MaxFloat(0, Abc_NodeReadArrivalWorst(pObj)) / pNtk->AndGateDelay);
159     }
160     // check that the CI/CO/latches are copied correctly
161     assert( Abc_NtkCiNum(pNtk)    == Abc_NtkCiNum(pNtkNew) );
162     assert( Abc_NtkCoNum(pNtk)    == Abc_NtkCoNum(pNtkNew) );
163     assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) );
164     return pNtkNew;
165 }
166 
167 /**Function*************************************************************
168 
169   Synopsis    [Starts a new network using existing network as a model.]
170 
171   Description []
172 
173   SideEffects []
174 
175   SeeAlso     []
176 
177 ***********************************************************************/
Abc_NtkStartFromWithLatches(Abc_Ntk_t * pNtk,Abc_NtkType_t Type,Abc_NtkFunc_t Func,int nLatches)178 Abc_Ntk_t * Abc_NtkStartFromWithLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func, int nLatches )
179 {
180     Abc_Ntk_t * pNtkNew;
181     Abc_Obj_t * pObj, * pNode0, * pNode1;
182     int fCopyNames, i;
183     if ( pNtk == NULL )
184         return NULL;
185     assert( Abc_NtkLatchNum(pNtk) == 0 );
186     // decide whether to copy the names
187     fCopyNames = ( Type != ABC_NTK_NETLIST );
188     // start the network
189     pNtkNew = Abc_NtkAlloc( Type, Func, 1 );
190     pNtkNew->nConstrs   = pNtk->nConstrs;
191     pNtkNew->nBarBufs   = pNtk->nBarBufs;
192     // duplicate the name and the spec
193     pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
194     pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
195     // clean the node copy fields
196     Abc_NtkCleanCopy( pNtk );
197     // map the constant nodes
198     if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) )
199         Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
200     // clone CIs/CIs/boxes
201     for ( i = 0; i < Abc_NtkPiNum(pNtk)-nLatches; i++ )
202         Abc_NtkDupObj( pNtkNew, Abc_NtkPi(pNtk, i), fCopyNames );
203     for ( i = 0; i < Abc_NtkPoNum(pNtk)-nLatches; i++ )
204         Abc_NtkDupObj( pNtkNew, Abc_NtkPo(pNtk, i), fCopyNames );
205     for ( i = 0; i < nLatches; i++ )
206     {
207         pObj = Abc_NtkCreateLatch(pNtkNew);
208         Abc_LatchSetInit0( pObj );
209         pNode0 = Abc_NtkCreateBi(pNtkNew);
210         Abc_NtkPo(pNtk, Abc_NtkPoNum(pNtk)-nLatches+i)->pCopy = pNode0;
211         pNode1 = Abc_NtkCreateBo(pNtkNew);
212         Abc_NtkPi(pNtk, Abc_NtkPiNum(pNtk)-nLatches+i)->pCopy = pNode1;
213         Abc_ObjAddFanin( pObj, pNode0 );
214         Abc_ObjAddFanin( pNode1, pObj );
215         Abc_ObjAssignName( pNode0, Abc_ObjName(pNode0), NULL );
216         Abc_ObjAssignName( pNode1, Abc_ObjName(pNode1), NULL );
217     }
218     // transfer logic level
219 //    Abc_NtkForEachCi( pNtk, pObj, i )
220 //        pObj->pCopy->Level = pObj->Level;
221     // transfer the names
222 //    Abc_NtkTrasferNames( pNtk, pNtkNew );
223     Abc_ManTimeDup( pNtk, pNtkNew );
224     if ( pNtk->vOnehots )
225         pNtkNew->vOnehots = (Vec_Ptr_t *)Vec_VecDupInt( (Vec_Vec_t *)pNtk->vOnehots );
226     if ( pNtk->pSeqModel )
227         pNtkNew->pSeqModel = Abc_CexDup( pNtk->pSeqModel, Abc_NtkLatchNum(pNtk) );
228     if ( pNtk->vObjPerm )
229         pNtkNew->vObjPerm = Vec_IntDup( pNtk->vObjPerm );
230     pNtkNew->AndGateDelay = pNtk->AndGateDelay;
231     // initialize logic level of the CIs
232     if ( pNtk->AndGateDelay != 0.0 && pNtk->pManTime != NULL && pNtk->ntkType != ABC_NTK_STRASH && Type == ABC_NTK_STRASH )
233     {
234         Abc_NtkForEachCi( pNtk, pObj, i )
235             pObj->pCopy->Level = (int)(Abc_MaxFloat(0, Abc_NodeReadArrivalWorst(pObj)) / pNtk->AndGateDelay);
236     }
237     // check that the CI/CO/latches are copied correctly
238     assert( Abc_NtkCiNum(pNtk)    == Abc_NtkCiNum(pNtkNew) );
239     assert( Abc_NtkCoNum(pNtk)    == Abc_NtkCoNum(pNtkNew) );
240     assert( nLatches              == Abc_NtkLatchNum(pNtkNew) );
241     return pNtkNew;
242 }
243 
244 /**Function*************************************************************
245 
246   Synopsis    [Starts a new network using existing network as a model.]
247 
248   Description []
249 
250   SideEffects []
251 
252   SeeAlso     []
253 
254 ***********************************************************************/
Abc_NtkStartFromNoLatches(Abc_Ntk_t * pNtk,Abc_NtkType_t Type,Abc_NtkFunc_t Func)255 Abc_Ntk_t * Abc_NtkStartFromNoLatches( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_t Func )
256 {
257     Abc_Ntk_t * pNtkNew;
258     Abc_Obj_t * pObj;
259     int i;
260     if ( pNtk == NULL )
261         return NULL;
262     assert( Type != ABC_NTK_NETLIST );
263     // start the network
264     pNtkNew = Abc_NtkAlloc( Type, Func, 1 );
265     pNtkNew->nConstrs   = pNtk->nConstrs;
266     pNtkNew->nBarBufs   = pNtk->nBarBufs;
267     // duplicate the name and the spec
268     pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
269     pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
270     // clean the node copy fields
271     Abc_NtkCleanCopy( pNtk );
272     // map the constant nodes
273     if ( Abc_NtkIsStrash(pNtk) && Abc_NtkIsStrash(pNtkNew) )
274         Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
275     // clone CIs/CIs/boxes
276     Abc_NtkForEachPi( pNtk, pObj, i )
277         Abc_NtkDupObj( pNtkNew, pObj, 1 );
278     Abc_NtkForEachPo( pNtk, pObj, i )
279         Abc_NtkDupObj( pNtkNew, pObj, 1 );
280     Abc_NtkForEachBox( pNtk, pObj, i )
281     {
282         if ( Abc_ObjIsLatch(pObj) )
283             continue;
284         Abc_NtkDupBox(pNtkNew, pObj, 1);
285     }
286     if ( pNtk->vObjPerm )
287         pNtkNew->vObjPerm = Vec_IntDup( pNtk->vObjPerm );
288     pNtkNew->AndGateDelay = pNtk->AndGateDelay;
289     // transfer the names
290 //    Abc_NtkTrasferNamesNoLatches( pNtk, pNtkNew );
291     Abc_ManTimeDup( pNtk, pNtkNew );
292     // check that the CI/CO/latches are copied correctly
293     assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) );
294     assert( Abc_NtkPoNum(pNtk) == Abc_NtkPoNum(pNtkNew) );
295     return pNtkNew;
296 }
297 
298 /**Function*************************************************************
299 
300   Synopsis    [Finalizes the network using the existing network as a model.]
301 
302   Description []
303 
304   SideEffects []
305 
306   SeeAlso     []
307 
308 ***********************************************************************/
Abc_NtkFinalize(Abc_Ntk_t * pNtk,Abc_Ntk_t * pNtkNew)309 void Abc_NtkFinalize( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew )
310 {
311     Abc_Obj_t * pObj, * pDriver, * pDriverNew;
312     int i;
313     // set the COs of the strashed network
314     Abc_NtkForEachCo( pNtk, pObj, i )
315     {
316         pDriver    = Abc_ObjFanin0Ntk( Abc_ObjFanin0(pObj) );
317         pDriverNew = Abc_ObjNotCond(pDriver->pCopy, Abc_ObjFaninC0(pObj));
318         Abc_ObjAddFanin( pObj->pCopy, pDriverNew );
319     }
320     // duplicate timing manager
321     if ( pNtk->pManTime )
322         Abc_NtkTimeInitialize( pNtkNew, pNtk );
323     if ( pNtk->vPhases )
324         Abc_NtkTransferPhases( pNtkNew, pNtk );
325     if ( pNtk->pWLoadUsed )
326         pNtkNew->pWLoadUsed = Abc_UtilStrsav( pNtk->pWLoadUsed );
327 }
328 
329 /**Function*************************************************************
330 
331   Synopsis    [Starts a new network using existing network as a model.]
332 
333   Description []
334 
335   SideEffects []
336 
337   SeeAlso     []
338 
339 ***********************************************************************/
Abc_NtkStartRead(char * pName)340 Abc_Ntk_t * Abc_NtkStartRead( char * pName )
341 {
342     Abc_Ntk_t * pNtkNew;
343     // allocate the empty network
344     pNtkNew = Abc_NtkAlloc( ABC_NTK_NETLIST, ABC_FUNC_SOP, 1 );
345     // set the specs
346     pNtkNew->pName = Extra_FileNameGeneric(pName);
347     pNtkNew->pSpec = Extra_UtilStrsav(pName);
348     if ( pNtkNew->pName == NULL || strlen(pNtkNew->pName) == 0 )
349     {
350         ABC_FREE( pNtkNew->pName );
351         pNtkNew->pName = Extra_UtilStrsav("unknown");
352     }
353     return pNtkNew;
354 }
355 
356 /**Function*************************************************************
357 
358   Synopsis    [Finalizes the network using the existing network as a model.]
359 
360   Description []
361 
362   SideEffects []
363 
364   SeeAlso     []
365 
366 ***********************************************************************/
Abc_NtkFinalizeRead(Abc_Ntk_t * pNtk)367 void Abc_NtkFinalizeRead( Abc_Ntk_t * pNtk )
368 {
369     Abc_Obj_t * pBox, * pObj, * pTerm, * pNet;
370     int i;
371     if ( Abc_NtkHasBlackbox(pNtk) && Abc_NtkBoxNum(pNtk) == 0 )
372     {
373         pBox = Abc_NtkCreateBlackbox(pNtk);
374         Abc_NtkForEachPi( pNtk, pObj, i )
375         {
376             pTerm = Abc_NtkCreateBi(pNtk);
377             Abc_ObjAddFanin( pTerm, Abc_ObjFanout0(pObj) );
378             Abc_ObjAddFanin( pBox, pTerm );
379         }
380         Abc_NtkForEachPo( pNtk, pObj, i )
381         {
382             pTerm = Abc_NtkCreateBo(pNtk);
383             Abc_ObjAddFanin( pTerm, pBox );
384             Abc_ObjAddFanin( Abc_ObjFanin0(pObj), pTerm );
385         }
386         return;
387     }
388     assert( Abc_NtkIsNetlist(pNtk) );
389 
390     // check if constant 0 net is used
391     pNet = Abc_NtkFindNet( pNtk, "1\'b0" );
392     if ( pNet )
393     {
394         if ( Abc_ObjFanoutNum(pNet) == 0 )
395             Abc_NtkDeleteObj(pNet);
396         else if ( Abc_ObjFaninNum(pNet) == 0 )
397             Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst0(pNtk) );
398     }
399     // check if constant 1 net is used
400     pNet = Abc_NtkFindNet( pNtk, "1\'b1" );
401     if ( pNet )
402     {
403         if ( Abc_ObjFanoutNum(pNet) == 0 )
404             Abc_NtkDeleteObj(pNet);
405         else if ( Abc_ObjFaninNum(pNet) == 0 )
406             Abc_ObjAddFanin( pNet, Abc_NtkCreateNodeConst1(pNtk) );
407     }
408     // fix the net drivers
409     Abc_NtkFixNonDrivenNets( pNtk );
410 
411     // reorder the CI/COs to PI/POs first
412     Abc_NtkOrderCisCos( pNtk );
413 }
414 
415 /**Function*************************************************************
416 
417   Synopsis    [Duplicate the network.]
418 
419   Description []
420 
421   SideEffects []
422 
423   SeeAlso     []
424 
425 ***********************************************************************/
Abc_NtkDup(Abc_Ntk_t * pNtk)426 Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
427 {
428     Abc_Ntk_t * pNtkNew;
429     Abc_Obj_t * pObj, * pFanin;
430     int i, k;
431     if ( pNtk == NULL )
432         return NULL;
433     // start the network
434     pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
435     // copy the internal nodes
436     if ( Abc_NtkIsStrash(pNtk) )
437     {
438         // copy the AND gates
439         Abc_AigForEachAnd( pNtk, pObj, i )
440             pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
441         // relink the choice nodes
442         Abc_AigForEachAnd( pNtk, pObj, i )
443             if ( pObj->pData )
444                 pObj->pCopy->pData = ((Abc_Obj_t *)pObj->pData)->pCopy;
445         // relink the CO nodes
446         Abc_NtkForEachCo( pNtk, pObj, i )
447             Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) );
448         // get the number of nodes before and after
449         if ( Abc_NtkNodeNum(pNtk) != Abc_NtkNodeNum(pNtkNew) )
450             printf( "Warning: Structural hashing during duplication reduced %d nodes (this is a minor bug).\n",
451                 Abc_NtkNodeNum(pNtk) - Abc_NtkNodeNum(pNtkNew) );
452     }
453     else
454     {
455         // duplicate the nets and nodes (CIs/COs/latches already dupped)
456         Abc_NtkForEachObj( pNtk, pObj, i )
457             if ( pObj->pCopy == NULL )
458                 Abc_NtkDupObj(pNtkNew, pObj, Abc_NtkHasBlackbox(pNtk) && Abc_ObjIsNet(pObj));
459         // reconnect all objects (no need to transfer attributes on edges)
460         Abc_NtkForEachObj( pNtk, pObj, i )
461             if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
462                 Abc_ObjForEachFanin( pObj, pFanin, k )
463                     Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
464     }
465     // duplicate the EXDC Ntk
466     if ( pNtk->pExdc )
467         pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
468     if ( pNtk->pExcare )
469         pNtkNew->pExcare = Abc_NtkDup( (Abc_Ntk_t *)pNtk->pExcare );
470     // duplicate timing manager
471     if ( pNtk->pManTime )
472         Abc_NtkTimeInitialize( pNtkNew, pNtk );
473     if ( pNtk->vPhases )
474         Abc_NtkTransferPhases( pNtkNew, pNtk );
475     if ( pNtk->pWLoadUsed )
476         pNtkNew->pWLoadUsed = Abc_UtilStrsav( pNtk->pWLoadUsed );
477     // check correctness
478     if ( !Abc_NtkCheck( pNtkNew ) )
479         fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
480     pNtk->pCopy = pNtkNew;
481     return pNtkNew;
482 }
Abc_NtkDupDfs(Abc_Ntk_t * pNtk)483 Abc_Ntk_t * Abc_NtkDupDfs( Abc_Ntk_t * pNtk )
484 {
485     Vec_Ptr_t * vNodes;
486     Abc_Ntk_t * pNtkNew;
487     Abc_Obj_t * pObj, * pFanin;
488     int i, k;
489     if ( pNtk == NULL )
490         return NULL;
491     assert( !Abc_NtkIsStrash(pNtk) && !Abc_NtkIsNetlist(pNtk) );
492     // start the network
493     pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
494     // copy the internal nodes
495     vNodes = Abc_NtkDfs( pNtk, 0 );
496     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
497         Abc_NtkDupObj( pNtkNew, pObj, 0 );
498     Vec_PtrFree( vNodes );
499     // reconnect all objects (no need to transfer attributes on edges)
500     Abc_NtkForEachObj( pNtk, pObj, i )
501         if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
502             Abc_ObjForEachFanin( pObj, pFanin, k )
503                 if ( pObj->pCopy && pFanin->pCopy )
504                     Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
505     // duplicate the EXDC Ntk
506     if ( pNtk->pExdc )
507         pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
508     if ( pNtk->pExcare )
509         pNtkNew->pExcare = Abc_NtkDup( (Abc_Ntk_t *)pNtk->pExcare );
510     // duplicate timing manager
511     if ( pNtk->pManTime )
512         Abc_NtkTimeInitialize( pNtkNew, pNtk );
513     if ( pNtk->vPhases )
514         Abc_NtkTransferPhases( pNtkNew, pNtk );
515     if ( pNtk->pWLoadUsed )
516         pNtkNew->pWLoadUsed = Abc_UtilStrsav( pNtk->pWLoadUsed );
517     // check correctness
518     if ( !Abc_NtkCheck( pNtkNew ) )
519         fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
520     pNtk->pCopy = pNtkNew;
521     return pNtkNew;
522 }
Abc_NtkDupDfsNoBarBufs(Abc_Ntk_t * pNtk)523 Abc_Ntk_t * Abc_NtkDupDfsNoBarBufs( Abc_Ntk_t * pNtk )
524 {
525     Vec_Ptr_t * vNodes;
526     Abc_Ntk_t * pNtkNew;
527     Abc_Obj_t * pObj, * pFanin;
528     int i, k;
529     if ( pNtk == NULL )
530         return NULL;
531     assert( Abc_NtkIsLogic(pNtk) );
532     assert( pNtk->nBarBufs2 > 0 );
533     // start the network
534     pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
535     // copy the internal nodes
536     vNodes = Abc_NtkDfs2( pNtk );
537     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
538         if ( Abc_ObjIsBarBuf(pObj) )
539             pObj->pCopy = Abc_ObjFanin0(pObj)->pCopy;
540         else
541             Abc_NtkDupObj( pNtkNew, pObj, 0 );
542     Vec_PtrFree( vNodes );
543     // reconnect all objects (no need to transfer attributes on edges)
544     Abc_NtkForEachObj( pNtk, pObj, i )
545         if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) && !Abc_ObjIsBarBuf(pObj) )
546             Abc_ObjForEachFanin( pObj, pFanin, k )
547                 if ( pObj->pCopy && pFanin->pCopy )
548                     Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
549     // duplicate the EXDC Ntk
550     if ( pNtk->pExdc )
551         pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
552     if ( pNtk->pExcare )
553         pNtkNew->pExcare = Abc_NtkDup( (Abc_Ntk_t *)pNtk->pExcare );
554     // duplicate timing manager
555     if ( pNtk->pManTime )
556         Abc_NtkTimeInitialize( pNtkNew, pNtk );
557     if ( pNtk->vPhases )
558         Abc_NtkTransferPhases( pNtkNew, pNtk );
559     if ( pNtk->pWLoadUsed )
560         pNtkNew->pWLoadUsed = Abc_UtilStrsav( pNtk->pWLoadUsed );
561     // check correctness
562     if ( !Abc_NtkCheck( pNtkNew ) )
563         fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
564     pNtk->pCopy = pNtkNew;
565     return pNtkNew;
566 }
567 
568 /**Function*************************************************************
569 
570   Synopsis    [Duplicate the AIG while adding latches.]
571 
572   Description []
573 
574   SideEffects []
575 
576   SeeAlso     []
577 
578 ***********************************************************************/
Abc_NtkRestrashWithLatches(Abc_Ntk_t * pNtk,int nLatches)579 Abc_Ntk_t * Abc_NtkRestrashWithLatches( Abc_Ntk_t * pNtk, int nLatches )
580 {
581     Abc_Ntk_t * pNtkAig;
582     Abc_Obj_t * pObj;
583     int i;
584     assert( Abc_NtkIsStrash(pNtk) );
585     // start the new network (constants and CIs of the old network will point to the their counterparts in the new network)
586     pNtkAig = Abc_NtkStartFromWithLatches( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG, nLatches );
587     // restrash the nodes (assuming a topological order of the old network)
588     Abc_NtkForEachNode( pNtk, pObj, i )
589         pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkAig->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
590     // finalize the network
591     Abc_NtkFinalize( pNtk, pNtkAig );
592     // make sure everything is okay
593     if ( !Abc_NtkCheck( pNtkAig ) )
594     {
595         printf( "Abc_NtkStrash: The network check has failed.\n" );
596         Abc_NtkDelete( pNtkAig );
597         return NULL;
598     }
599     return pNtkAig;
600 
601 }
602 
603 /**Function*************************************************************
604 
605   Synopsis    [Duplicate the network.]
606 
607   Description []
608 
609   SideEffects []
610 
611   SeeAlso     []
612 
613 ***********************************************************************/
Abc_NtkDupTransformMiter(Abc_Ntk_t * pNtk)614 Abc_Ntk_t * Abc_NtkDupTransformMiter( Abc_Ntk_t * pNtk )
615 {
616     Abc_Ntk_t * pNtkNew;
617     Abc_Obj_t * pObj, * pObj2, * pMiter;
618     int i;
619     assert( Abc_NtkIsStrash(pNtk) );
620     // start the network
621     pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
622     pNtkNew->nConstrs   = pNtk->nConstrs;
623     pNtkNew->nBarBufs   = pNtk->nBarBufs;
624     // duplicate the name and the spec
625     pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
626     pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
627     // clean the node copy fields
628     Abc_NtkCleanCopy( pNtk );
629     // map the constant nodes
630      Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
631     // clone CIs/CIs/boxes
632     Abc_NtkForEachPi( pNtk, pObj, i )
633         Abc_NtkDupObj( pNtkNew, pObj, 1 );
634     Abc_NtkForEachPo( pNtk, pObj, i )
635         Abc_NtkDupObj( pNtkNew, pObj, 1 ), i++;
636     Abc_NtkForEachBox( pNtk, pObj, i )
637         Abc_NtkDupBox( pNtkNew, pObj, 1 );
638     // copy the AND gates
639     Abc_AigForEachAnd( pNtk, pObj, i )
640         pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
641     // create new miters
642     Abc_NtkForEachPo( pNtk, pObj, i )
643     {
644         pObj2 = Abc_NtkPo( pNtk, ++i );
645         pMiter = Abc_AigXor( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild0Copy(pObj2) );
646         Abc_ObjAddFanin( pObj->pCopy, pMiter );
647     }
648     Abc_NtkForEachLatchInput( pNtk, pObj, i )
649         Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) );
650     // cleanup
651     Abc_AigCleanup( (Abc_Aig_t *)pNtkNew->pManFunc );
652     // check that the CI/CO/latches are copied correctly
653     assert( Abc_NtkPiNum(pNtk) == Abc_NtkPiNum(pNtkNew) );
654     assert( Abc_NtkPoNum(pNtk) == 2*Abc_NtkPoNum(pNtkNew) );
655     assert( Abc_NtkLatchNum(pNtk) == Abc_NtkLatchNum(pNtkNew) );
656     return pNtkNew;
657 }
658 
659 /**Function*************************************************************
660 
661   Synopsis    [Duplicate the network.]
662 
663   Description []
664 
665   SideEffects []
666 
667   SeeAlso     []
668 
669 ***********************************************************************/
Abc_NtkDouble(Abc_Ntk_t * pNtk)670 Abc_Ntk_t * Abc_NtkDouble( Abc_Ntk_t * pNtk )
671 {
672     char Buffer[500];
673     Abc_Ntk_t * pNtkNew;
674     Abc_Obj_t * pObj, * pFanin;
675     int i, k;
676     assert( Abc_NtkIsLogic(pNtk) );
677 
678     // start the network
679     pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
680     sprintf( Buffer, "%s%s", pNtk->pName, "_2x" );
681     pNtkNew->pName = Extra_UtilStrsav(Buffer);
682 
683     // clean the node copy fields
684     Abc_NtkCleanCopy( pNtk );
685     // clone CIs/CIs/boxes
686     Abc_NtkForEachPi( pNtk, pObj, i )
687         Abc_NtkDupObj( pNtkNew, pObj, 0 );
688     Abc_NtkForEachPo( pNtk, pObj, i )
689         Abc_NtkDupObj( pNtkNew, pObj, 0 );
690     Abc_NtkForEachBox( pNtk, pObj, i )
691         Abc_NtkDupBox( pNtkNew, pObj, 0 );
692     // copy the internal nodes
693     // duplicate the nets and nodes (CIs/COs/latches already dupped)
694     Abc_NtkForEachObj( pNtk, pObj, i )
695         if ( pObj->pCopy == NULL )
696             Abc_NtkDupObj(pNtkNew, pObj, 0);
697     // reconnect all objects (no need to transfer attributes on edges)
698     Abc_NtkForEachObj( pNtk, pObj, i )
699         if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
700             Abc_ObjForEachFanin( pObj, pFanin, k )
701                 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
702 
703     // clean the node copy fields
704     Abc_NtkCleanCopy( pNtk );
705     // clone CIs/CIs/boxes
706     Abc_NtkForEachPi( pNtk, pObj, i )
707         Abc_NtkDupObj( pNtkNew, pObj, 0 );
708     Abc_NtkForEachPo( pNtk, pObj, i )
709         Abc_NtkDupObj( pNtkNew, pObj, 0 );
710     Abc_NtkForEachBox( pNtk, pObj, i )
711         Abc_NtkDupBox( pNtkNew, pObj, 0 );
712     // copy the internal nodes
713     // duplicate the nets and nodes (CIs/COs/latches already dupped)
714     Abc_NtkForEachObj( pNtk, pObj, i )
715         if ( pObj->pCopy == NULL )
716             Abc_NtkDupObj(pNtkNew, pObj, 0);
717     // reconnect all objects (no need to transfer attributes on edges)
718     Abc_NtkForEachObj( pNtk, pObj, i )
719         if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
720             Abc_ObjForEachFanin( pObj, pFanin, k )
721                 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
722 
723     // assign names
724     Abc_NtkForEachCi( pNtk, pObj, i )
725     {
726         Abc_ObjAssignName( Abc_NtkCi(pNtkNew,                      i), "1_", Abc_ObjName(pObj) );
727         Abc_ObjAssignName( Abc_NtkCi(pNtkNew, Abc_NtkCiNum(pNtk) + i), "2_", Abc_ObjName(pObj) );
728     }
729     Abc_NtkForEachCo( pNtk, pObj, i )
730     {
731         Abc_ObjAssignName( Abc_NtkCo(pNtkNew,                      i), "1_", Abc_ObjName(pObj) );
732         Abc_ObjAssignName( Abc_NtkCo(pNtkNew, Abc_NtkCoNum(pNtk) + i), "2_", Abc_ObjName(pObj) );
733     }
734     Abc_NtkOrderCisCos( pNtkNew );
735 
736     // perform the final check
737     if ( !Abc_NtkCheck( pNtkNew ) )
738         fprintf( stdout, "Abc_NtkDup(): Network check has failed.\n" );
739     return pNtkNew;
740 }
741 
742 /**Function*************************************************************
743 
744   Synopsis    [Duplicate the bottom levels of the network.]
745 
746   Description []
747 
748   SideEffects []
749 
750   SeeAlso     []
751 
752 ***********************************************************************/
Abc_NtkBottom(Abc_Ntk_t * pNtk,int Level)753 Abc_Ntk_t * Abc_NtkBottom( Abc_Ntk_t * pNtk, int Level )
754 {
755     char Buffer[500];
756     Abc_Ntk_t * pNtkNew;
757     Abc_Obj_t * pObj, * pFanin;
758     int i, k;
759     assert( Abc_NtkIsLogic(pNtk) );
760     assert( Abc_NtkLatchNum(pNtk) == 0 );
761 
762     // start the network
763     pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
764     sprintf( Buffer, "%s%s", pNtk->pName, "_bot" );
765     pNtkNew->pName = Extra_UtilStrsav(Buffer);
766 
767     // clean the node copy fields
768     Abc_NtkCleanCopy( pNtk );
769     // clone CIs/CIs/boxes
770     Abc_NtkForEachPi( pNtk, pObj, i )
771         Abc_NtkDupObj( pNtkNew, pObj, 1 );
772 
773     // copy the internal nodes
774     // duplicate the nets and nodes (CIs/COs/latches already dupped)
775     Abc_NtkForEachObj( pNtk, pObj, i )
776         if ( pObj->pCopy == NULL && Abc_ObjIsNode(pObj) && Abc_ObjLevel(pObj) <= Level )
777             Abc_NtkDupObj(pNtkNew, pObj, 0);
778     // reconnect all objects (no need to transfer attributes on edges)
779     Abc_NtkForEachObj( pNtk, pObj, i )
780         Abc_ObjForEachFanin( pObj, pFanin, k )
781             if ( pObj->pCopy && pFanin->pCopy )
782                 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
783 
784     // create new primary outputs
785     Abc_NtkForEachObj( pNtk, pObj, i )
786         Abc_ObjForEachFanin( pObj, pFanin, k )
787             if ( !pObj->pCopy && pFanin->pCopy && Abc_ObjIsNode(pFanin) )
788             {
789                 Abc_Obj_t * pNodeNew = Abc_NtkCreatePo(pNtkNew);
790                 Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
791                 Abc_ObjAssignName( pNodeNew, Abc_ObjName(pNodeNew), NULL );
792             }
793 
794     // perform the final check
795     if ( !Abc_NtkCheck( pNtkNew ) )
796         fprintf( stdout, "Abc_NtkBottom(): Network check has failed.\n" );
797     return pNtkNew;
798 }
799 
800 /**Function*************************************************************
801 
802   Synopsis    [Attaches the second network at the bottom of the first.]
803 
804   Description [Returns the first network. Deletes the second network.]
805 
806   SideEffects []
807 
808   SeeAlso     []
809 
810 ***********************************************************************/
Abc_NtkAttachBottom(Abc_Ntk_t * pNtkTop,Abc_Ntk_t * pNtkBottom)811 Abc_Ntk_t * Abc_NtkAttachBottom( Abc_Ntk_t * pNtkTop, Abc_Ntk_t * pNtkBottom )
812 {
813     Abc_Obj_t * pObj, * pFanin, * pBuffer;
814     Vec_Ptr_t * vNodes;
815     int i, k;
816     assert( pNtkBottom != NULL );
817     if ( pNtkTop == NULL )
818         return pNtkBottom;
819     // make sure the networks are combinational
820     assert( Abc_NtkPiNum(pNtkTop) == Abc_NtkCiNum(pNtkTop) );
821     assert( Abc_NtkPiNum(pNtkBottom) == Abc_NtkCiNum(pNtkBottom) );
822     // make sure the POs of the bottom correspond to the PIs of the top
823     assert( Abc_NtkPoNum(pNtkBottom) == Abc_NtkPiNum(pNtkTop) );
824     assert( Abc_NtkPiNum(pNtkBottom) <  Abc_NtkPiNum(pNtkTop) );
825     // add buffers for the PIs of the top - save results in the POs of the bottom
826     Abc_NtkForEachPi( pNtkTop, pObj, i )
827     {
828         pBuffer = Abc_NtkCreateNodeBuf( pNtkTop, NULL );
829         Abc_ObjTransferFanout( pObj, pBuffer );
830         Abc_NtkPo(pNtkBottom, i)->pCopy = pBuffer;
831     }
832     // remove useless PIs of the top
833     for ( i = Abc_NtkPiNum(pNtkTop) - 1; i >= Abc_NtkPiNum(pNtkBottom); i-- )
834         Abc_NtkDeleteObj( Abc_NtkPi(pNtkTop, i) );
835     assert( Abc_NtkPiNum(pNtkBottom) == Abc_NtkPiNum(pNtkTop) );
836     // copy the bottom network
837     Abc_NtkForEachPi( pNtkBottom, pObj, i )
838         Abc_NtkPi(pNtkBottom, i)->pCopy = Abc_NtkPi(pNtkTop, i);
839     // construct all nodes
840     vNodes = Abc_NtkDfs( pNtkBottom, 0 );
841     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
842     {
843         Abc_NtkDupObj(pNtkTop, pObj, 0);
844         Abc_ObjForEachFanin( pObj, pFanin, k )
845             Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
846     }
847     Vec_PtrFree( vNodes );
848     // connect the POs
849     Abc_NtkForEachPo( pNtkBottom, pObj, i )
850         Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pObj)->pCopy );
851     // delete old network
852     Abc_NtkDelete( pNtkBottom );
853     // return the network
854     if ( !Abc_NtkCheck( pNtkTop ) )
855         fprintf( stdout, "Abc_NtkAttachBottom(): Network check has failed.\n" );
856     return pNtkTop;
857 }
858 
859 /**Function*************************************************************
860 
861   Synopsis    [Creates the network composed of one logic cone.]
862 
863   Description []
864 
865   SideEffects []
866 
867   SeeAlso     []
868 
869 ***********************************************************************/
Abc_NtkCreateCone(Abc_Ntk_t * pNtk,Abc_Obj_t * pNode,char * pNodeName,int fUseAllCis)870 Abc_Ntk_t * Abc_NtkCreateCone( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNodeName, int fUseAllCis )
871 {
872     Abc_Ntk_t * pNtkNew;
873     Vec_Ptr_t * vNodes;
874     Abc_Obj_t * pObj, * pFanin, * pNodeCoNew;
875     char Buffer[1000];
876     int i, k;
877 
878     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) );
879     assert( Abc_ObjIsNode(pNode) || (Abc_NtkIsStrash(pNtk) && (Abc_AigNodeIsConst(pNode) || Abc_ObjIsCi(pNode)))  );
880 
881     // start the network
882     pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
883     // set the name
884     sprintf( Buffer, "%s_%s", pNtk->pName, pNodeName );
885     pNtkNew->pName = Extra_UtilStrsav(Buffer);
886 
887     // establish connection between the constant nodes
888     if ( Abc_NtkIsStrash(pNtk) )
889         Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
890 
891     // collect the nodes in the TFI of the output (mark the TFI)
892     vNodes = Abc_NtkDfsNodes( pNtk, &pNode, 1 );
893     // create the PIs
894     Abc_NtkForEachCi( pNtk, pObj, i )
895     {
896         if ( fUseAllCis || Abc_NodeIsTravIdCurrent(pObj) ) // TravId is set by DFS
897         {
898             pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
899             Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL );
900         }
901     }
902     // add the PO corresponding to this output
903     pNodeCoNew = Abc_NtkCreatePo( pNtkNew );
904     Abc_ObjAssignName( pNodeCoNew, pNodeName, NULL );
905     // copy the nodes
906     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
907     {
908         // if it is an AIG, add to the hash table
909         if ( Abc_NtkIsStrash(pNtk) )
910         {
911             pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
912         }
913         else
914         {
915             Abc_NtkDupObj( pNtkNew, pObj, 0 );
916             Abc_ObjForEachFanin( pObj, pFanin, k )
917                 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
918         }
919     }
920     // connect the internal nodes to the new CO
921     Abc_ObjAddFanin( pNodeCoNew, pNode->pCopy );
922     Vec_PtrFree( vNodes );
923 
924     if ( !Abc_NtkCheck( pNtkNew ) )
925         fprintf( stdout, "Abc_NtkCreateCone(): Network check has failed.\n" );
926     return pNtkNew;
927 }
928 
929 /**Function*************************************************************
930 
931   Synopsis    [Creates the network composed of several logic cones.]
932 
933   Description []
934 
935   SideEffects []
936 
937   SeeAlso     []
938 
939 ***********************************************************************/
Abc_NtkCreateConeArray(Abc_Ntk_t * pNtk,Vec_Ptr_t * vRoots,int fUseAllCis)940 Abc_Ntk_t * Abc_NtkCreateConeArray( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, int fUseAllCis )
941 {
942     Abc_Ntk_t * pNtkNew;
943     Vec_Ptr_t * vNodes;
944     Abc_Obj_t * pObj, * pFanin, * pNodeCoNew;
945     char Buffer[1000];
946     int i, k;
947 
948     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) );
949 
950     // start the network
951     pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
952     // set the name
953     sprintf( Buffer, "%s_part", pNtk->pName );
954     pNtkNew->pName = Extra_UtilStrsav(Buffer);
955 
956     // establish connection between the constant nodes
957     if ( Abc_NtkIsStrash(pNtk) )
958         Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
959 
960     // collect the nodes in the TFI of the output (mark the TFI)
961     vNodes = Abc_NtkDfsNodes( pNtk, (Abc_Obj_t **)Vec_PtrArray(vRoots), Vec_PtrSize(vRoots) );
962 
963     // create the PIs
964     Abc_NtkForEachCi( pNtk, pObj, i )
965     {
966         if ( fUseAllCis || Abc_NodeIsTravIdCurrent(pObj) ) // TravId is set by DFS
967         {
968             pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
969             Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL );
970         }
971     }
972 
973     // copy the nodes
974     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
975     {
976         // if it is an AIG, add to the hash table
977         if ( Abc_NtkIsStrash(pNtk) )
978         {
979             pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
980         }
981         else
982         {
983             Abc_NtkDupObj( pNtkNew, pObj, 0 );
984             Abc_ObjForEachFanin( pObj, pFanin, k )
985                 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
986         }
987     }
988     Vec_PtrFree( vNodes );
989 
990     // add the POs corresponding to the root nodes
991     Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i )
992     {
993         // create the PO node
994         pNodeCoNew = Abc_NtkCreatePo( pNtkNew );
995         // connect the internal nodes to the new CO
996         if ( Abc_ObjIsCo(pObj) )
997             Abc_ObjAddFanin( pNodeCoNew, Abc_ObjChild0Copy(pObj) );
998         else
999             Abc_ObjAddFanin( pNodeCoNew, pObj->pCopy );
1000         // assign the name
1001         Abc_ObjAssignName( pNodeCoNew, Abc_ObjName(pObj), NULL );
1002     }
1003 
1004     if ( !Abc_NtkCheck( pNtkNew ) )
1005         fprintf( stdout, "Abc_NtkCreateConeArray(): Network check has failed.\n" );
1006     return pNtkNew;
1007 }
1008 
1009 /**Function*************************************************************
1010 
1011   Synopsis    [Adds new nodes to the cone.]
1012 
1013   Description []
1014 
1015   SideEffects []
1016 
1017   SeeAlso     []
1018 
1019 ***********************************************************************/
Abc_NtkAppendToCone(Abc_Ntk_t * pNtkNew,Abc_Ntk_t * pNtk,Vec_Ptr_t * vRoots)1020 void Abc_NtkAppendToCone( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots )
1021 {
1022     Vec_Ptr_t * vNodes;
1023     Abc_Obj_t * pObj;
1024     int i, iNodeId;
1025 
1026     assert( Abc_NtkIsStrash(pNtkNew) );
1027     assert( Abc_NtkIsStrash(pNtk) );
1028 
1029     // collect the nodes in the TFI of the output (mark the TFI)
1030     vNodes = Abc_NtkDfsNodes( pNtk, (Abc_Obj_t **)Vec_PtrArray(vRoots), Vec_PtrSize(vRoots) );
1031 
1032     // establish connection between the constant nodes
1033     Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
1034 
1035     // create the PIs
1036     Abc_NtkForEachCi( pNtk, pObj, i )
1037     {
1038         // skip CIs that are not used
1039         if ( !Abc_NodeIsTravIdCurrent(pObj) )
1040             continue;
1041         // find the corresponding CI in the new network
1042         iNodeId = Nm_ManFindIdByNameTwoTypes( pNtkNew->pManName, Abc_ObjName(pObj), ABC_OBJ_PI, ABC_OBJ_BO );
1043         if ( iNodeId == -1 )
1044         {
1045             pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
1046             Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL );
1047         }
1048         else
1049             pObj->pCopy = Abc_NtkObj( pNtkNew, iNodeId );
1050     }
1051 
1052     // copy the nodes
1053     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
1054         pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
1055     Vec_PtrFree( vNodes );
1056 
1057     // do not add the COs
1058     if ( !Abc_NtkCheck( pNtkNew ) )
1059         fprintf( stdout, "Abc_NtkAppendToCone(): Network check has failed.\n" );
1060 }
1061 
1062 /**Function*************************************************************
1063 
1064   Synopsis    [Creates the network composed of MFFC of one node.]
1065 
1066   Description []
1067 
1068   SideEffects []
1069 
1070   SeeAlso     []
1071 
1072 ***********************************************************************/
Abc_NtkCreateMffc(Abc_Ntk_t * pNtk,Abc_Obj_t * pNode,char * pNodeName)1073 Abc_Ntk_t * Abc_NtkCreateMffc( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode, char * pNodeName )
1074 {
1075     Abc_Ntk_t * pNtkNew;
1076     Abc_Obj_t * pObj, * pFanin, * pNodeCoNew;
1077     Vec_Ptr_t * vCone, * vSupp;
1078     char Buffer[1000];
1079     int i, k;
1080 
1081     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) );
1082     assert( Abc_ObjIsNode(pNode) );
1083 
1084     // start the network
1085     pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
1086     // set the name
1087     sprintf( Buffer, "%s_%s", pNtk->pName, pNodeName );
1088     pNtkNew->pName = Extra_UtilStrsav(Buffer);
1089 
1090     // establish connection between the constant nodes
1091     if ( Abc_NtkIsStrash(pNtk) )
1092         Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
1093 
1094     // collect the nodes in MFFC
1095     vCone = Vec_PtrAlloc( 100 );
1096     vSupp = Vec_PtrAlloc( 100 );
1097     Abc_NodeDeref_rec( pNode );
1098     Abc_NodeMffcConeSupp( pNode, vCone, vSupp );
1099     Abc_NodeRef_rec( pNode );
1100     // create the PIs
1101     Vec_PtrForEachEntry( Abc_Obj_t *, vSupp, pObj, i )
1102     {
1103         pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
1104         Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL );
1105     }
1106     // create the PO
1107     pNodeCoNew = Abc_NtkCreatePo( pNtkNew );
1108     Abc_ObjAssignName( pNodeCoNew, pNodeName, NULL );
1109     // copy the nodes
1110     Vec_PtrForEachEntry( Abc_Obj_t *, vCone, pObj, i )
1111     {
1112         // if it is an AIG, add to the hash table
1113         if ( Abc_NtkIsStrash(pNtk) )
1114         {
1115             pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
1116         }
1117         else
1118         {
1119             Abc_NtkDupObj( pNtkNew, pObj, 0 );
1120             Abc_ObjForEachFanin( pObj, pFanin, k )
1121                 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
1122         }
1123     }
1124     // connect the topmost node
1125     Abc_ObjAddFanin( pNodeCoNew, pNode->pCopy );
1126     Vec_PtrFree( vCone );
1127     Vec_PtrFree( vSupp );
1128 
1129     if ( !Abc_NtkCheck( pNtkNew ) )
1130         fprintf( stdout, "Abc_NtkCreateMffc(): Network check has failed.\n" );
1131     return pNtkNew;
1132 }
1133 
1134 /**Function*************************************************************
1135 
1136   Synopsis    [Creates the miter composed of one multi-output cone.]
1137 
1138   Description []
1139 
1140   SideEffects []
1141 
1142   SeeAlso     []
1143 
1144 ***********************************************************************/
Abc_NtkCreateTarget(Abc_Ntk_t * pNtk,Vec_Ptr_t * vRoots,Vec_Int_t * vValues)1145 Abc_Ntk_t * Abc_NtkCreateTarget( Abc_Ntk_t * pNtk, Vec_Ptr_t * vRoots, Vec_Int_t * vValues )
1146 {
1147     Vec_Ptr_t * vNodes;
1148     Abc_Ntk_t * pNtkNew;
1149     Abc_Obj_t * pObj, * pFinal, * pOther, * pNodePo;
1150     int i;
1151 
1152     assert( Abc_NtkIsLogic(pNtk) );
1153 
1154     // start the network
1155     Abc_NtkCleanCopy( pNtk );
1156     pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
1157     pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
1158 
1159     // collect the nodes in the TFI of the output
1160     vNodes = Abc_NtkDfsNodes( pNtk, (Abc_Obj_t **)vRoots->pArray, vRoots->nSize );
1161     // create the PIs
1162     Abc_NtkForEachCi( pNtk, pObj, i )
1163     {
1164         pObj->pCopy = Abc_NtkCreatePi(pNtkNew);
1165         Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL );
1166     }
1167     // copy the nodes
1168     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
1169         pObj->pCopy = Abc_NodeStrash( pNtkNew, pObj, 0 );
1170     Vec_PtrFree( vNodes );
1171 
1172     // add the PO
1173     pFinal = Abc_AigConst1( pNtkNew );
1174     Vec_PtrForEachEntry( Abc_Obj_t *, vRoots, pObj, i )
1175     {
1176         if ( Abc_ObjIsCo(pObj) )
1177             pOther = Abc_ObjFanin0(pObj)->pCopy;
1178         else
1179             pOther = pObj->pCopy;
1180         if ( Vec_IntEntry(vValues, i) == 0 )
1181             pOther = Abc_ObjNot(pOther);
1182         pFinal = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, pFinal, pOther );
1183     }
1184 
1185     // add the PO corresponding to this output
1186     pNodePo = Abc_NtkCreatePo( pNtkNew );
1187     Abc_ObjAddFanin( pNodePo, pFinal );
1188     Abc_ObjAssignName( pNodePo, "miter", NULL );
1189     if ( !Abc_NtkCheck( pNtkNew ) )
1190         fprintf( stdout, "Abc_NtkCreateTarget(): Network check has failed.\n" );
1191     return pNtkNew;
1192 }
1193 
1194 /**Function*************************************************************
1195 
1196   Synopsis    [Creates the network composed of one node.]
1197 
1198   Description []
1199 
1200   SideEffects []
1201 
1202   SeeAlso     []
1203 
1204 ***********************************************************************/
Abc_NtkCreateFromNode(Abc_Ntk_t * pNtk,Abc_Obj_t * pNode)1205 Abc_Ntk_t * Abc_NtkCreateFromNode( Abc_Ntk_t * pNtk, Abc_Obj_t * pNode )
1206 {
1207     Abc_Ntk_t * pNtkNew;
1208     Abc_Obj_t * pFanin, * pNodePo;
1209     int i;
1210     // start the network
1211     pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
1212     pNtkNew->pName = Extra_UtilStrsav(Abc_ObjName(pNode));
1213     // add the PIs corresponding to the fanins of the node
1214     Abc_ObjForEachFanin( pNode, pFanin, i )
1215     {
1216         pFanin->pCopy = Abc_NtkCreatePi( pNtkNew );
1217         Abc_ObjAssignName( pFanin->pCopy, Abc_ObjName(pFanin), NULL );
1218     }
1219     // duplicate and connect the node
1220     pNode->pCopy = Abc_NtkDupObj( pNtkNew, pNode, 0 );
1221     Abc_ObjForEachFanin( pNode, pFanin, i )
1222         Abc_ObjAddFanin( pNode->pCopy, pFanin->pCopy );
1223     // create the only PO
1224     pNodePo = Abc_NtkCreatePo( pNtkNew );
1225     Abc_ObjAddFanin( pNodePo, pNode->pCopy );
1226     Abc_ObjAssignName( pNodePo, Abc_ObjName(pNode), NULL );
1227     if ( !Abc_NtkCheck( pNtkNew ) )
1228         fprintf( stdout, "Abc_NtkCreateFromNode(): Network check has failed.\n" );
1229     return pNtkNew;
1230 }
1231 
1232 /**Function*************************************************************
1233 
1234   Synopsis    [Creates the network composed of one node with the given SOP.]
1235 
1236   Description []
1237 
1238   SideEffects []
1239 
1240   SeeAlso     []
1241 
1242 ***********************************************************************/
Abc_NtkCreateWithNode(char * pSop)1243 Abc_Ntk_t * Abc_NtkCreateWithNode( char * pSop )
1244 {
1245     Abc_Ntk_t * pNtkNew;
1246     Abc_Obj_t * pFanin, * pNode, * pNodePo;
1247     Vec_Ptr_t * vNames;
1248     int i, nVars;
1249     // start the network
1250     pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
1251     pNtkNew->pName = Extra_UtilStrsav("ex");
1252     // create PIs
1253     Vec_PtrPush( pNtkNew->vObjs, NULL );
1254     nVars = Abc_SopGetVarNum( pSop );
1255     vNames = Abc_NodeGetFakeNames( nVars );
1256     for ( i = 0; i < nVars; i++ )
1257         Abc_ObjAssignName( Abc_NtkCreatePi(pNtkNew), (char *)Vec_PtrEntry(vNames, i), NULL );
1258     Abc_NodeFreeNames( vNames );
1259     // create the node, add PIs as fanins, set the function
1260     pNode = Abc_NtkCreateNode( pNtkNew );
1261     Abc_NtkForEachPi( pNtkNew, pFanin, i )
1262         Abc_ObjAddFanin( pNode, pFanin );
1263     pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, pSop );
1264     // create the only PO
1265     pNodePo = Abc_NtkCreatePo(pNtkNew);
1266     Abc_ObjAddFanin( pNodePo, pNode );
1267     Abc_ObjAssignName( pNodePo, "F", NULL );
1268     if ( !Abc_NtkCheck( pNtkNew ) )
1269         fprintf( stdout, "Abc_NtkCreateWithNode(): Network check has failed.\n" );
1270     return pNtkNew;
1271 }
1272 
1273 /**Function*************************************************************
1274 
1275   Synopsis    [Deletes the Ntk.]
1276 
1277   Description []
1278 
1279   SideEffects []
1280 
1281   SeeAlso     []
1282 
1283 ***********************************************************************/
Abc_NtkDelete(Abc_Ntk_t * pNtk)1284 void Abc_NtkDelete( Abc_Ntk_t * pNtk )
1285 {
1286     Abc_Obj_t * pObj;
1287     void * pAttrMan;
1288     int TotalMemory, i;
1289 //    int LargePiece = (4 << ABC_NUM_STEPS);
1290     if ( pNtk == NULL )
1291         return;
1292     // free EXDC Ntk
1293     if ( pNtk->pExdc )
1294         Abc_NtkDelete( pNtk->pExdc );
1295     if ( pNtk->pExcare )
1296         Abc_NtkDelete( (Abc_Ntk_t *)pNtk->pExcare );
1297     // dereference the BDDs
1298     if ( Abc_NtkHasBdd(pNtk) )
1299     {
1300 #ifdef ABC_USE_CUDD
1301         Abc_NtkForEachNode( pNtk, pObj, i )
1302             Cudd_RecursiveDeref( (DdManager *)pNtk->pManFunc, (DdNode *)pObj->pData );
1303 #endif
1304     }
1305     // make sure all the marks are clean
1306     Abc_NtkForEachObj( pNtk, pObj, i )
1307     {
1308         // free large fanout arrays
1309 //        if ( pNtk->pMmObj && pObj->vFanouts.nCap * 4 > LargePiece )
1310 //            ABC_FREE( pObj->vFanouts.pArray );
1311         // these flags should be always zero
1312         // if this is not true, something is wrong somewhere
1313         assert( pObj->fMarkA == 0 );
1314         assert( pObj->fMarkB == 0 );
1315         assert( pObj->fMarkC == 0 );
1316     }
1317     // free the nodes
1318     if ( pNtk->pMmStep == NULL )
1319     {
1320         Abc_NtkForEachObj( pNtk, pObj, i )
1321         {
1322             ABC_FREE( pObj->vFanouts.pArray );
1323             ABC_FREE( pObj->vFanins.pArray );
1324         }
1325     }
1326     if ( pNtk->pMmObj == NULL )
1327     {
1328         Abc_NtkForEachObj( pNtk, pObj, i )
1329             ABC_FREE( pObj );
1330     }
1331 
1332     // free the arrays
1333     Vec_PtrFree( pNtk->vPios );
1334     Vec_PtrFree( pNtk->vPis );
1335     Vec_PtrFree( pNtk->vPos );
1336     Vec_PtrFree( pNtk->vCis );
1337     Vec_PtrFree( pNtk->vCos );
1338     Vec_PtrFree( pNtk->vObjs );
1339     Vec_PtrFree( pNtk->vBoxes );
1340     ABC_FREE( pNtk->vTravIds.pArray );
1341     if ( pNtk->vLevelsR ) Vec_IntFree( pNtk->vLevelsR );
1342     ABC_FREE( pNtk->pModel );
1343     ABC_FREE( pNtk->pSeqModel );
1344     if ( pNtk->vSeqModelVec )
1345         Vec_PtrFreeFree( pNtk->vSeqModelVec );
1346     TotalMemory  = 0;
1347     TotalMemory += pNtk->pMmObj? Mem_FixedReadMemUsage(pNtk->pMmObj)  : 0;
1348     TotalMemory += pNtk->pMmStep? Mem_StepReadMemUsage(pNtk->pMmStep) : 0;
1349 //    fprintf( stdout, "The total memory allocated internally by the network = %0.2f MB.\n", ((double)TotalMemory)/(1<<20) );
1350     // free the storage
1351     if ( pNtk->pMmObj )
1352         Mem_FixedStop( pNtk->pMmObj, 0 );
1353     if ( pNtk->pMmStep )
1354         Mem_StepStop ( pNtk->pMmStep, 0 );
1355     // name manager
1356     Nm_ManFree( pNtk->pManName );
1357     // free the timing manager
1358     if ( pNtk->pManTime )
1359         Abc_ManTimeStop( pNtk->pManTime );
1360     Vec_IntFreeP( &pNtk->vPhases );
1361     // start the functionality manager
1362     if ( Abc_NtkIsStrash(pNtk) )
1363         Abc_AigFree( (Abc_Aig_t *)pNtk->pManFunc );
1364     else if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) )
1365         Mem_FlexStop( (Mem_Flex_t *)pNtk->pManFunc, 0 );
1366 #ifdef ABC_USE_CUDD
1367     else if ( Abc_NtkHasBdd(pNtk) )
1368         Extra_StopManager( (DdManager *)pNtk->pManFunc );
1369 #endif
1370     else if ( Abc_NtkHasAig(pNtk) )
1371         { if ( pNtk->pManFunc ) Hop_ManStop( (Hop_Man_t *)pNtk->pManFunc ); }
1372     else if ( Abc_NtkHasMapping(pNtk) )
1373         pNtk->pManFunc = NULL;
1374     else if ( !Abc_NtkHasBlackbox(pNtk) )
1375         assert( 0 );
1376     // free the hierarchy
1377     if ( pNtk->pDesign )
1378     {
1379         Abc_DesFree( pNtk->pDesign, pNtk );
1380         pNtk->pDesign = NULL;
1381     }
1382 //    if ( pNtk->pBlackBoxes )
1383 //        Vec_IntFree( pNtk->pBlackBoxes );
1384     // free node attributes
1385     Vec_PtrForEachEntry( Abc_Obj_t *, pNtk->vAttrs, pAttrMan, i )
1386         if ( pAttrMan )
1387             Vec_AttFree( (Vec_Att_t *)pAttrMan, 1 );
1388     assert( pNtk->pSCLib == NULL );
1389     Vec_IntFreeP( &pNtk->vGates );
1390     Vec_PtrFree( pNtk->vAttrs );
1391     Vec_IntFreeP( &pNtk->vNameIds );
1392     ABC_FREE( pNtk->pWLoadUsed );
1393     ABC_FREE( pNtk->pName );
1394     ABC_FREE( pNtk->pSpec );
1395     ABC_FREE( pNtk->pLutTimes );
1396     if ( pNtk->vOnehots )
1397         Vec_VecFree( (Vec_Vec_t *)pNtk->vOnehots );
1398     Vec_PtrFreeP( &pNtk->vLtlProperties );
1399     Vec_IntFreeP( &pNtk->vObjPerm );
1400     Vec_IntFreeP( &pNtk->vTopo );
1401     Vec_IntFreeP( &pNtk->vFins );
1402     ABC_FREE( pNtk );
1403 }
1404 
1405 /**Function*************************************************************
1406 
1407   Synopsis    [Reads the verilog file.]
1408 
1409   Description []
1410 
1411   SideEffects []
1412 
1413   SeeAlso     []
1414 
1415 ***********************************************************************/
Abc_NtkFixNonDrivenNets(Abc_Ntk_t * pNtk)1416 void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
1417 {
1418     Vec_Ptr_t * vNets;
1419     Abc_Obj_t * pNet, * pNode;
1420     int i;
1421 
1422     if ( Abc_NtkNodeNum(pNtk) == 0 && Abc_NtkBoxNum(pNtk) == 0 )
1423         return;
1424 
1425     // special case
1426     pNet = Abc_NtkFindNet( pNtk, "[_c1_]" );
1427     if ( pNet != NULL )
1428     {
1429         pNode = Abc_NtkCreateNodeConst1( pNtk );
1430         Abc_ObjAddFanin( pNet, pNode );
1431     }
1432 
1433     // check for non-driven nets
1434     vNets = Vec_PtrAlloc( 100 );
1435     Abc_NtkForEachNet( pNtk, pNet, i )
1436     {
1437         if ( Abc_ObjFaninNum(pNet) > 0 )
1438             continue;
1439         // add the constant 0 driver
1440         pNode = Abc_NtkCreateNodeConst0( pNtk );
1441         // add the fanout net
1442         Abc_ObjAddFanin( pNet, pNode );
1443         // add the net to those for which the warning will be printed
1444         Vec_PtrPush( vNets, pNet );
1445     }
1446 
1447     // print the warning
1448     if ( vNets->nSize > 0 )
1449     {
1450         printf( "Warning: Constant-0 drivers added to %d non-driven nets in network \"%s\":\n", Vec_PtrSize(vNets), pNtk->pName );
1451         Vec_PtrForEachEntry( Abc_Obj_t *, vNets, pNet, i )
1452         {
1453             printf( "%s%s", (i? ", ": ""), Abc_ObjName(pNet) );
1454             if ( i == 3 )
1455             {
1456                 if ( Vec_PtrSize(vNets) > 3 )
1457                     printf( " ..." );
1458                 break;
1459             }
1460         }
1461         printf( "\n" );
1462     }
1463     Vec_PtrFree( vNets );
1464 }
1465 
1466 
1467 /**Function*************************************************************
1468 
1469   Synopsis    [Converts the network to combinational.]
1470 
1471   Description []
1472 
1473   SideEffects []
1474 
1475   SeeAlso     []
1476 
1477 ***********************************************************************/
Abc_NtkMakeComb(Abc_Ntk_t * pNtk,int fRemoveLatches)1478 void Abc_NtkMakeComb( Abc_Ntk_t * pNtk, int fRemoveLatches )
1479 {
1480     Abc_Obj_t * pObj;
1481     int i;
1482 
1483     if ( Abc_NtkIsComb(pNtk) )
1484         return;
1485 
1486     assert( !Abc_NtkIsNetlist(pNtk) );
1487     assert( Abc_NtkHasOnlyLatchBoxes(pNtk) );
1488 
1489     // detach the latches
1490 //    Abc_NtkForEachLatch( pNtk, pObj, i )
1491     Vec_PtrForEachEntryReverse( Abc_Obj_t *, pNtk->vBoxes, pObj, i )
1492         Abc_NtkDeleteObj( pObj );
1493     assert( Abc_NtkLatchNum(pNtk) == 0 );
1494     assert( Abc_NtkBoxNum(pNtk) == 0 );
1495 
1496     // move CIs to become PIs
1497     Vec_PtrClear( pNtk->vPis );
1498     Abc_NtkForEachCi( pNtk, pObj, i )
1499     {
1500         if ( Abc_ObjIsBo(pObj) )
1501         {
1502             pObj->Type = ABC_OBJ_PI;
1503             pNtk->nObjCounts[ABC_OBJ_PI]++;
1504             pNtk->nObjCounts[ABC_OBJ_BO]--;
1505         }
1506         Vec_PtrPush( pNtk->vPis, pObj );
1507     }
1508     assert( Abc_NtkBoNum(pNtk) == 0 );
1509 
1510     if ( fRemoveLatches )
1511     {
1512         // remove registers
1513         Vec_Ptr_t * vBos;
1514         vBos = Vec_PtrAlloc( 100 );
1515         Vec_PtrClear( pNtk->vPos );
1516         Abc_NtkForEachCo( pNtk, pObj, i )
1517             if ( Abc_ObjIsBi(pObj) )
1518                 Vec_PtrPush( vBos, pObj );
1519             else
1520                 Vec_PtrPush( pNtk->vPos, pObj );
1521         // remove COs
1522         Vec_PtrFree( pNtk->vCos );
1523         pNtk->vCos = NULL;
1524         // remove the BOs
1525         Vec_PtrForEachEntry( Abc_Obj_t *, vBos, pObj, i )
1526             Abc_NtkDeleteObj( pObj );
1527         Vec_PtrFree( vBos );
1528         // create COs
1529         pNtk->vCos = Vec_PtrDup( pNtk->vPos );
1530         // cleanup
1531         if ( Abc_NtkIsLogic(pNtk) )
1532             Abc_NtkCleanup( pNtk, 0 );
1533         else if ( Abc_NtkIsStrash(pNtk) )
1534             Abc_AigCleanup( (Abc_Aig_t *)pNtk->pManFunc );
1535         else
1536             assert( 0 );
1537     }
1538     else
1539     {
1540         // move COs to become POs
1541         Vec_PtrClear( pNtk->vPos );
1542         Abc_NtkForEachCo( pNtk, pObj, i )
1543         {
1544             if ( Abc_ObjIsBi(pObj) )
1545             {
1546                 pObj->Type = ABC_OBJ_PO;
1547                 pNtk->nObjCounts[ABC_OBJ_PO]++;
1548                 pNtk->nObjCounts[ABC_OBJ_BI]--;
1549             }
1550             Vec_PtrPush( pNtk->vPos, pObj );
1551         }
1552     }
1553     assert( Abc_NtkBiNum(pNtk) == 0 );
1554 
1555     if ( !Abc_NtkCheck( pNtk ) )
1556         fprintf( stdout, "Abc_NtkMakeComb(): Network check has failed.\n" );
1557 }
1558 
1559 /**Function*************************************************************
1560 
1561   Synopsis    [Converts the network to sequential.]
1562 
1563   Description []
1564 
1565   SideEffects []
1566 
1567   SeeAlso     []
1568 
1569 ***********************************************************************/
Abc_NtkMakeSeq(Abc_Ntk_t * pNtk,int nLatchesToAdd)1570 void Abc_NtkMakeSeq( Abc_Ntk_t * pNtk, int nLatchesToAdd )
1571 {
1572     Abc_Obj_t * pObjLi, * pObjLo, * pObj;
1573     int i;
1574     assert( Abc_NtkBoxNum(pNtk) == 0 );
1575     if ( !Abc_NtkIsComb(pNtk) )
1576     {
1577         printf( "The network is a not a combinational one.\n" );
1578         return;
1579     }
1580     if ( nLatchesToAdd >= Abc_NtkPiNum(pNtk) )
1581     {
1582         printf( "The number of latches is more or equal than the number of PIs.\n" );
1583         return;
1584     }
1585     if ( nLatchesToAdd >= Abc_NtkPoNum(pNtk) )
1586     {
1587         printf( "The number of latches is more or equal than the number of POs.\n" );
1588         return;
1589     }
1590 
1591     // move the last PIs to become CIs
1592     Vec_PtrClear( pNtk->vPis );
1593     Abc_NtkForEachCi( pNtk, pObj, i )
1594     {
1595         if ( i < Abc_NtkCiNum(pNtk) - nLatchesToAdd )
1596         {
1597             Vec_PtrPush( pNtk->vPis, pObj );
1598             continue;
1599         }
1600         pObj->Type = ABC_OBJ_BO;
1601         pNtk->nObjCounts[ABC_OBJ_PI]--;
1602         pNtk->nObjCounts[ABC_OBJ_BO]++;
1603     }
1604 
1605     // move the last POs to become COs
1606     Vec_PtrClear( pNtk->vPos );
1607     Abc_NtkForEachCo( pNtk, pObj, i )
1608     {
1609         if ( i < Abc_NtkCoNum(pNtk) - nLatchesToAdd )
1610         {
1611             Vec_PtrPush( pNtk->vPos, pObj );
1612             continue;
1613         }
1614         pObj->Type = ABC_OBJ_BI;
1615         pNtk->nObjCounts[ABC_OBJ_PO]--;
1616         pNtk->nObjCounts[ABC_OBJ_BI]++;
1617     }
1618 
1619     // create latches
1620     for ( i = 0; i < nLatchesToAdd; i++ )
1621     {
1622         pObjLo = Abc_NtkCi( pNtk, Abc_NtkCiNum(pNtk) - nLatchesToAdd + i );
1623         pObjLi = Abc_NtkCo( pNtk, Abc_NtkCoNum(pNtk) - nLatchesToAdd + i );
1624         pObj = Abc_NtkCreateLatch( pNtk );
1625         Abc_ObjAddFanin( pObj, pObjLi );
1626         Abc_ObjAddFanin( pObjLo, pObj );
1627         Abc_LatchSetInit0( pObj );
1628     }
1629 
1630     if ( !Abc_NtkCheck( pNtk ) )
1631         fprintf( stdout, "Abc_NtkMakeSeq(): Network check has failed.\n" );
1632 }
1633 
1634 
1635 /**Function*************************************************************
1636 
1637   Synopsis    [Removes all POs, except one.]
1638 
1639   Description []
1640 
1641   SideEffects []
1642 
1643   SeeAlso     []
1644 
1645 ***********************************************************************/
Abc_NtkMakeOnePo(Abc_Ntk_t * pNtkInit,int Output,int nRange)1646 Abc_Ntk_t * Abc_NtkMakeOnePo( Abc_Ntk_t * pNtkInit, int Output, int nRange )
1647 {
1648     Abc_Ntk_t * pNtk;
1649     Vec_Ptr_t * vPosLeft;
1650     Vec_Ptr_t * vCosLeft;
1651     Abc_Obj_t * pNodePo;
1652     int i;
1653     assert( !Abc_NtkIsNetlist(pNtkInit) );
1654     assert( Abc_NtkHasOnlyLatchBoxes(pNtkInit) );
1655     if ( Output < 0 || Output >= Abc_NtkPoNum(pNtkInit) )
1656     {
1657         printf( "PO index is incorrect.\n" );
1658         return NULL;
1659     }
1660 
1661     pNtk = Abc_NtkDup( pNtkInit );
1662     if ( Abc_NtkPoNum(pNtk) == 1 )
1663         return pNtk;
1664 
1665     if ( nRange < 1 )
1666         nRange = 1;
1667 
1668     // filter POs
1669     vPosLeft = Vec_PtrAlloc( nRange );
1670     Abc_NtkForEachPo( pNtk, pNodePo, i )
1671         if ( i < Output || i >= Output + nRange )
1672             Abc_NtkDeleteObjPo( pNodePo );
1673         else
1674             Vec_PtrPush( vPosLeft, pNodePo );
1675     // filter COs
1676     vCosLeft = Vec_PtrDup( vPosLeft );
1677     for ( i = Abc_NtkPoNum(pNtk); i < Abc_NtkCoNum(pNtk); i++ )
1678         Vec_PtrPush( vCosLeft, Abc_NtkCo(pNtk, i) );
1679     // update arrays
1680     Vec_PtrFree( pNtk->vPos );  pNtk->vPos = vPosLeft;
1681     Vec_PtrFree( pNtk->vCos );  pNtk->vCos = vCosLeft;
1682 
1683     // clean the network
1684     if ( Abc_NtkIsStrash(pNtk) )
1685     {
1686         Abc_AigCleanup( (Abc_Aig_t *)pNtk->pManFunc );
1687         printf( "Run sequential cleanup (\"scl\") to get rid of dangling logic.\n" );
1688     }
1689     else
1690     {
1691         printf( "Run sequential cleanup (\"st; scl\") to get rid of dangling logic.\n" );
1692     }
1693 
1694     if ( !Abc_NtkCheck( pNtk ) )
1695         fprintf( stdout, "Abc_NtkMakeComb(): Network check has failed.\n" );
1696     return pNtk;
1697 }
1698 
1699 /**Function*************************************************************
1700 
1701   Synopsis    [Removes POs with suppsize less than 2 and PIs without fanout.]
1702 
1703   Description []
1704 
1705   SideEffects []
1706 
1707   SeeAlso     []
1708 
1709 ***********************************************************************/
Abc_NtkTrim(Abc_Ntk_t * pNtk)1710 Abc_Ntk_t * Abc_NtkTrim( Abc_Ntk_t * pNtk )
1711 {
1712     Abc_Obj_t * pObj;
1713     int i, k, m;
1714 
1715     // filter POs
1716     k = m = 0;
1717     Abc_NtkForEachCo( pNtk, pObj, i )
1718     {
1719         if ( Abc_ObjIsPo(pObj) )
1720         {
1721             // remove constant nodes and PI pointers
1722             if ( Abc_ObjFaninNum(Abc_ObjFanin0(pObj)) == 0 )
1723             {
1724                 Abc_ObjDeleteFanin( pObj, Abc_ObjFanin0(pObj) );
1725                 if ( Abc_ObjFanoutNum(Abc_ObjFanin0(pObj)) == 0 && !Abc_ObjIsPi(Abc_ObjFanin0(pObj)) )
1726                     Abc_NtkDeleteObj_rec( Abc_ObjFanin0(pObj), 1 );
1727                 pNtk->vObjs->pArray[pObj->Id] = NULL;
1728                 pObj->Id = (1<<26)-1;
1729                 pNtk->nObjCounts[pObj->Type]--;
1730                 pNtk->nObjs--;
1731                 Abc_ObjRecycle( pObj );
1732                 continue;
1733             }
1734             // remove buffers/inverters of PIs
1735             if ( Abc_ObjFaninNum(Abc_ObjFanin0(pObj)) == 1 )
1736             {
1737                 if ( Abc_ObjIsPi(Abc_ObjFanin0(Abc_ObjFanin0(pObj))) )
1738                 {
1739                     Abc_ObjDeleteFanin( pObj, Abc_ObjFanin0(pObj) );
1740                     if ( Abc_ObjFanoutNum(Abc_ObjFanin0(pObj)) == 0 )
1741                         Abc_NtkDeleteObj_rec( Abc_ObjFanin0(pObj), 1 );
1742                     pNtk->vObjs->pArray[pObj->Id] = NULL;
1743                     pObj->Id = (1<<26)-1;
1744                     pNtk->nObjCounts[pObj->Type]--;
1745                     pNtk->nObjs--;
1746                     Abc_ObjRecycle( pObj );
1747                     continue;
1748                 }
1749             }
1750             Vec_PtrWriteEntry( pNtk->vPos, m++, pObj );
1751         }
1752         Vec_PtrWriteEntry( pNtk->vCos, k++, pObj );
1753     }
1754     Vec_PtrShrink( pNtk->vPos, m );
1755     Vec_PtrShrink( pNtk->vCos, k );
1756 
1757     // filter PIs
1758     k = m = 0;
1759     Abc_NtkForEachCi( pNtk, pObj, i )
1760     {
1761         if ( Abc_ObjIsPi(pObj) )
1762         {
1763             if ( Abc_ObjFanoutNum(pObj) == 0 )
1764             {
1765                 pNtk->vObjs->pArray[pObj->Id] = NULL;
1766                 pObj->Id = (1<<26)-1;
1767                 pNtk->nObjCounts[pObj->Type]--;
1768                 pNtk->nObjs--;
1769                 Abc_ObjRecycle( pObj );
1770                 continue;
1771             }
1772             Vec_PtrWriteEntry( pNtk->vPis, m++, pObj );
1773         }
1774         Vec_PtrWriteEntry( pNtk->vCis, k++, pObj );
1775     }
1776     Vec_PtrShrink( pNtk->vPis, m );
1777     Vec_PtrShrink( pNtk->vCis, k );
1778 
1779     return Abc_NtkDup( pNtk );
1780 }
1781 
1782 /**Function*************************************************************
1783 
1784   Synopsis    []
1785 
1786   Description []
1787 
1788   SideEffects []
1789 
1790   SeeAlso     []
1791 
1792 ***********************************************************************/
Abc_NtkDropSatOutputs(Abc_Ntk_t * pNtk,Vec_Ptr_t * vCexes,int fVerbose)1793 void Abc_NtkDropSatOutputs( Abc_Ntk_t * pNtk, Vec_Ptr_t * vCexes, int fVerbose )
1794 {
1795     Abc_Obj_t * pObj, * pConst0, * pFaninNew;
1796     int i, Counter = 0;
1797     assert( Vec_PtrSize(vCexes) == Abc_NtkPoNum(pNtk) );
1798     pConst0 = Abc_ObjNot( Abc_AigConst1(pNtk) );
1799     Abc_NtkForEachPo( pNtk, pObj, i )
1800     {
1801         if ( Vec_PtrEntry( vCexes, i ) == NULL )
1802             continue;
1803         Counter++;
1804         pFaninNew = Abc_ObjNotCond( pConst0, Abc_ObjFaninC0(pObj) );
1805         Abc_ObjPatchFanin( pObj, Abc_ObjFanin0(pObj), pFaninNew );
1806         assert( Abc_ObjChild0(pObj) == pConst0 );
1807         // if a PO is driven by a latch, they have the same name...
1808 //        if ( Abc_ObjIsBo(pObj) )
1809 //            Nm_ManDeleteIdName( pNtk->pManName, Abc_ObjId(pObj) );
1810     }
1811     if ( fVerbose )
1812         printf( "Logic cones of %d POs have been replaced by constant 0.\n", Counter );
1813     Counter = Abc_AigCleanup( (Abc_Aig_t *)pNtk->pManFunc );
1814 //    printf( "Cleanup removed %d nodes.\n", Counter );
1815 }
1816 
1817 /**Function*************************************************************
1818 
1819   Synopsis    []
1820 
1821   Description []
1822 
1823   SideEffects []
1824 
1825   SeeAlso     []
1826 
1827 ***********************************************************************/
Abc_NtkDropOneOutput(Abc_Ntk_t * pNtk,int iOutput,int fSkipSweep,int fUseConst1)1828 void Abc_NtkDropOneOutput( Abc_Ntk_t * pNtk, int iOutput, int fSkipSweep, int fUseConst1 )
1829 {
1830     Abc_Obj_t * pObj, * pConst0, * pFaninNew;
1831     pObj = Abc_NtkPo( pNtk, iOutput );
1832     if ( Abc_ObjFanin0(pObj) == Abc_AigConst1(pNtk) )
1833     {
1834         if ( !Abc_ObjFaninC0(pObj) ^ fUseConst1 )
1835             Abc_ObjXorFaninC( pObj, 0 );
1836         return;
1837     }
1838     pConst0 = Abc_ObjNotCond( Abc_AigConst1(pNtk), !fUseConst1 );
1839     pFaninNew = Abc_ObjNotCond( pConst0, Abc_ObjFaninC0(pObj) );
1840     Abc_ObjPatchFanin( pObj, Abc_ObjFanin0(pObj), pFaninNew );
1841     assert( Abc_ObjChild0(pObj) == pConst0 );
1842     if ( fSkipSweep )
1843         return;
1844     Abc_AigCleanup( (Abc_Aig_t *)pNtk->pManFunc );
1845 }
1846 
1847 /**Function*************************************************************
1848 
1849   Synopsis    []
1850 
1851   Description []
1852 
1853   SideEffects []
1854 
1855   SeeAlso     []
1856 
1857 ***********************************************************************/
Abc_NtkSwapOneOutput(Abc_Ntk_t * pNtk,int iOutput)1858 void Abc_NtkSwapOneOutput( Abc_Ntk_t * pNtk, int iOutput )
1859 {
1860     Abc_Obj_t * pObj1, * pObj2;
1861     Abc_Obj_t * pChild1Old, * pChild2Old;
1862     Abc_Obj_t * pChild1, * pChild2;
1863     if ( iOutput == 0 )
1864         return;
1865     pObj1      = Abc_NtkPo( pNtk, 0 );
1866     pObj2      = Abc_NtkPo( pNtk, iOutput );
1867     if ( Abc_ObjFanin0(pObj1) == Abc_ObjFanin0(pObj2) )
1868     {
1869         if ( Abc_ObjFaninC0(pObj1) ^ Abc_ObjFaninC0(pObj2) )
1870         {
1871             Abc_ObjXorFaninC( pObj1, 0 );
1872             Abc_ObjXorFaninC( pObj2, 0 );
1873         }
1874         return;
1875     }
1876     pChild1Old = Abc_ObjChild0( pObj1 );
1877     pChild2Old = Abc_ObjChild0( pObj2 );
1878     pChild1    = Abc_ObjNotCond( pChild1Old, Abc_ObjFaninC0(pObj2) );
1879     pChild2    = Abc_ObjNotCond( pChild2Old, Abc_ObjFaninC0(pObj1) );
1880     Abc_ObjPatchFanin( pObj1, Abc_ObjFanin0(pObj1), pChild2 );
1881     Abc_ObjPatchFanin( pObj2, Abc_ObjFanin0(pObj2), pChild1 );
1882     assert( Abc_ObjChild0(pObj1) == pChild2Old );
1883     assert( Abc_ObjChild0(pObj2) == pChild1Old );
1884 }
1885 
1886 /**Function*************************************************************
1887 
1888   Synopsis    []
1889 
1890   Description []
1891 
1892   SideEffects []
1893 
1894   SeeAlso     []
1895 
1896 ***********************************************************************/
Abc_NtkRemovePo(Abc_Ntk_t * pNtk,int iOutput,int fRemoveConst0)1897 void Abc_NtkRemovePo( Abc_Ntk_t * pNtk, int iOutput, int fRemoveConst0 )
1898 {
1899     Abc_Obj_t * pObj = Abc_NtkPo(pNtk, iOutput);
1900     if ( Abc_ObjFanin0(pObj) == Abc_AigConst1(pNtk) && Abc_ObjFaninC0(pObj) == fRemoveConst0 )
1901         Abc_NtkDeleteObj( pObj );
1902 }
1903 
1904 /**Function*************************************************************
1905 
1906   Synopsis    []
1907 
1908   Description []
1909 
1910   SideEffects []
1911 
1912   SeeAlso     []
1913 
1914 ***********************************************************************/
Abc_NtkReadFlopPerm(char * pFileName,int nFlops)1915 Vec_Int_t * Abc_NtkReadFlopPerm( char * pFileName, int nFlops )
1916 {
1917     char Buffer[1000];
1918     FILE * pFile;
1919     Vec_Int_t * vFlops;
1920     int iFlop = -1;
1921     pFile = fopen( pFileName, "rb" );
1922     if ( pFile == NULL )
1923     {
1924         printf( "Cannot open input file \"%s\".\n", pFileName );
1925         return NULL;
1926     }
1927     vFlops = Vec_IntAlloc( nFlops );
1928     while ( fgets( Buffer, 1000, pFile ) != NULL )
1929     {
1930         if ( Buffer[0] == ' ' || Buffer[0] == '\r' || Buffer[0] == '\n' )
1931             continue;
1932         iFlop = atoi( Buffer );
1933         if ( iFlop < 0 || iFlop >= nFlops )
1934         {
1935             printf( "Flop ID (%d) is out of range.\n", iFlop );
1936             fclose( pFile );
1937             Vec_IntFree( vFlops );
1938             return NULL;
1939         }
1940         Vec_IntPush( vFlops, iFlop );
1941     }
1942     fclose( pFile );
1943     if ( Vec_IntSize(vFlops) != nFlops )
1944     {
1945         printf( "The number of flops read in from file (%d) is different from the number of flops in the circuit (%d).\n", iFlop, nFlops );
1946         Vec_IntFree( vFlops );
1947         return NULL;
1948     }
1949     return vFlops;
1950 }
1951 /**Function*************************************************************
1952 
1953   Synopsis    []
1954 
1955   Description []
1956 
1957   SideEffects []
1958 
1959   SeeAlso     []
1960 
1961 ***********************************************************************/
Abc_NtkPermute(Abc_Ntk_t * pNtk,int fInputs,int fOutputs,int fFlops,char * pFlopPermFile)1962 void Abc_NtkPermute( Abc_Ntk_t * pNtk, int fInputs, int fOutputs, int fFlops, char * pFlopPermFile )
1963 {
1964     Abc_Obj_t * pTemp;
1965     Vec_Int_t * vInputs, * vOutputs, * vFlops, * vTemp;
1966     int i, k, Entry;
1967     // start permutation arrays
1968     if ( pFlopPermFile )
1969     {
1970         vFlops = Abc_NtkReadFlopPerm( pFlopPermFile, Abc_NtkLatchNum(pNtk) );
1971         if ( vFlops == NULL )
1972             return;
1973         fInputs  = 0;
1974         fOutputs = 0;
1975         fFlops   = 0;
1976     }
1977     else
1978         vFlops   = Vec_IntStartNatural( Abc_NtkLatchNum(pNtk) );
1979     vInputs  = Vec_IntStartNatural( Abc_NtkPiNum(pNtk) );
1980     vOutputs = Vec_IntStartNatural( Abc_NtkPoNum(pNtk) );
1981     // permute inputs
1982     if ( fInputs )
1983     for ( i = 0; i < Abc_NtkPiNum(pNtk); i++ )
1984     {
1985         k = rand() % Abc_NtkPiNum(pNtk);
1986         // swap indexes
1987         Entry = Vec_IntEntry( vInputs, i );
1988         Vec_IntWriteEntry( vInputs, i, Vec_IntEntry(vInputs, k) );
1989         Vec_IntWriteEntry( vInputs, k, Entry );
1990         // swap PIs
1991         pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vPis, i );
1992         Vec_PtrWriteEntry( pNtk->vPis, i, Vec_PtrEntry(pNtk->vPis, k) );
1993         Vec_PtrWriteEntry( pNtk->vPis, k, pTemp );
1994         // swap CIs
1995         pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCis, i );
1996         Vec_PtrWriteEntry( pNtk->vCis, i, Vec_PtrEntry(pNtk->vCis, k) );
1997         Vec_PtrWriteEntry( pNtk->vCis, k, pTemp );
1998 //printf( "Swapping PIs %d and %d.\n", i, k );
1999     }
2000     // permute outputs
2001     if ( fOutputs )
2002     for ( i = 0; i < Abc_NtkPoNum(pNtk); i++ )
2003     {
2004         k = rand() % Abc_NtkPoNum(pNtk);
2005         // swap indexes
2006         Entry = Vec_IntEntry( vOutputs, i );
2007         Vec_IntWriteEntry( vOutputs, i, Vec_IntEntry(vOutputs, k) );
2008         Vec_IntWriteEntry( vOutputs, k, Entry );
2009         // swap POs
2010         pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vPos, i );
2011         Vec_PtrWriteEntry( pNtk->vPos, i, Vec_PtrEntry(pNtk->vPos, k) );
2012         Vec_PtrWriteEntry( pNtk->vPos, k, pTemp );
2013         // swap COs
2014         pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCos, i );
2015         Vec_PtrWriteEntry( pNtk->vCos, i, Vec_PtrEntry(pNtk->vCos, k) );
2016         Vec_PtrWriteEntry( pNtk->vCos, k, pTemp );
2017 //printf( "Swapping POs %d and %d.\n", i, k );
2018     }
2019     // permute flops
2020     assert( Abc_NtkBoxNum(pNtk) == Abc_NtkLatchNum(pNtk) );
2021     if ( fFlops )
2022     for ( i = 0; i < Abc_NtkLatchNum(pNtk); i++ )
2023     {
2024         k = rand() % Abc_NtkLatchNum(pNtk);
2025         // swap indexes
2026         Entry = Vec_IntEntry( vFlops, i );
2027         Vec_IntWriteEntry( vFlops, i, Vec_IntEntry(vFlops, k) );
2028         Vec_IntWriteEntry( vFlops, k, Entry );
2029         // swap flops
2030         pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vBoxes, i );
2031         Vec_PtrWriteEntry( pNtk->vBoxes, i, Vec_PtrEntry(pNtk->vBoxes, k) );
2032         Vec_PtrWriteEntry( pNtk->vBoxes, k, pTemp );
2033         // swap CIs
2034         pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCis, Abc_NtkPiNum(pNtk)+i );
2035         Vec_PtrWriteEntry( pNtk->vCis, Abc_NtkPiNum(pNtk)+i, Vec_PtrEntry(pNtk->vCis, Abc_NtkPiNum(pNtk)+k) );
2036         Vec_PtrWriteEntry( pNtk->vCis, Abc_NtkPiNum(pNtk)+k, pTemp );
2037         // swap COs
2038         pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCos, Abc_NtkPoNum(pNtk)+i );
2039         Vec_PtrWriteEntry( pNtk->vCos, Abc_NtkPoNum(pNtk)+i, Vec_PtrEntry(pNtk->vCos, Abc_NtkPoNum(pNtk)+k) );
2040         Vec_PtrWriteEntry( pNtk->vCos, Abc_NtkPoNum(pNtk)+k, pTemp );
2041 
2042 //printf( "Swapping flops %d and %d.\n", i, k );
2043     }
2044     // invert arrays
2045     vInputs = Vec_IntInvert( vTemp = vInputs, -1 );
2046     Vec_IntFree( vTemp );
2047     vOutputs = Vec_IntInvert( vTemp = vOutputs, -1 );
2048     Vec_IntFree( vTemp );
2049     vFlops = Vec_IntInvert( vTemp = vFlops, -1 );
2050     Vec_IntFree( vTemp );
2051     // pack the results into the output array
2052     Vec_IntFreeP( &pNtk->vObjPerm );
2053     pNtk->vObjPerm = Vec_IntAlloc( Abc_NtkPiNum(pNtk) + Abc_NtkPoNum(pNtk) + Abc_NtkLatchNum(pNtk) );
2054     Vec_IntForEachEntry( vInputs, Entry, i )
2055         Vec_IntPush( pNtk->vObjPerm, Entry );
2056     Vec_IntForEachEntry( vOutputs, Entry, i )
2057         Vec_IntPush( pNtk->vObjPerm, Entry );
2058     Vec_IntForEachEntry( vFlops, Entry, i )
2059         Vec_IntPush( pNtk->vObjPerm, Entry );
2060     // cleanup
2061     Vec_IntFree( vInputs );
2062     Vec_IntFree( vOutputs );
2063     Vec_IntFree( vFlops );
2064 }
2065 
2066 /**Function*************************************************************
2067 
2068   Synopsis    []
2069 
2070   Description []
2071 
2072   SideEffects []
2073 
2074   SeeAlso     []
2075 
2076 ***********************************************************************/
Abc_NodeCompareByFanoutCount(Abc_Obj_t ** pp1,Abc_Obj_t ** pp2)2077 int Abc_NodeCompareByFanoutCount( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
2078 {
2079     int Diff = Abc_ObjFanoutNum(*pp2) - Abc_ObjFanoutNum(*pp1);
2080     if ( Diff < 0 )
2081         return -1;
2082     if ( Diff > 0 )
2083         return 1;
2084     Diff = strcmp( Abc_ObjName(*pp1), Abc_ObjName(*pp2) );
2085     if ( Diff < 0 )
2086         return -1;
2087     if ( Diff > 0 )
2088         return 1;
2089     return 0;
2090 }
Abc_NtkPermutePiUsingFanout(Abc_Ntk_t * pNtk)2091 void Abc_NtkPermutePiUsingFanout( Abc_Ntk_t * pNtk )
2092 {
2093     Abc_Obj_t * pNode; int i;
2094     qsort( (void *)Vec_PtrArray(pNtk->vPis), (size_t)Vec_PtrSize(pNtk->vPis), sizeof(Abc_Obj_t *),
2095         (int (*)(const void *, const void *)) Abc_NodeCompareByFanoutCount );
2096     Vec_PtrClear( pNtk->vCis );
2097     Vec_PtrForEachEntry( Abc_Obj_t *, pNtk->vPis, pNode, i )
2098         Vec_PtrPush( pNtk->vCis, pNode );
2099 }
2100 
2101 /**Function*************************************************************
2102 
2103   Synopsis    []
2104 
2105   Description []
2106 
2107   SideEffects []
2108 
2109   SeeAlso     []
2110 
2111 ***********************************************************************/
Abc_NtkUnpermute(Abc_Ntk_t * pNtk)2112 void Abc_NtkUnpermute( Abc_Ntk_t * pNtk )
2113 {
2114     Vec_Ptr_t * vTemp, * vTemp2, * vLatch;
2115     int i, * pInputs, * pOutputs, * pFlops;
2116     if ( pNtk->vObjPerm == NULL )
2117     {
2118         printf( "Abc_NtkUnpermute(): Initial permutation is not available.\n" );
2119         return;
2120     }
2121     assert( Abc_NtkBoxNum(pNtk) == Abc_NtkLatchNum(pNtk) );
2122     // get reverve permutation
2123     pInputs  = Vec_IntArray( pNtk->vObjPerm );
2124     pOutputs = pInputs  + Abc_NtkPiNum(pNtk);
2125     pFlops   = pOutputs + Abc_NtkPoNum(pNtk);
2126     // create new PI array
2127     vTemp = Vec_PtrAlloc( Abc_NtkPiNum(pNtk) );
2128     for ( i = 0; i < Abc_NtkPiNum(pNtk); i++ )
2129         Vec_PtrPush( vTemp, Abc_NtkPi(pNtk, pInputs[i]) );
2130     Vec_PtrFreeP( &pNtk->vPis );
2131     pNtk->vPis = vTemp;
2132     // create new PO array
2133     vTemp = Vec_PtrAlloc( Abc_NtkPoNum(pNtk) );
2134     for ( i = 0; i < Abc_NtkPoNum(pNtk); i++ )
2135         Vec_PtrPush( vTemp, Abc_NtkPo(pNtk, pOutputs[i]) );
2136     Vec_PtrFreeP( &pNtk->vPos );
2137     pNtk->vPos = vTemp;
2138     // create new CI/CO arrays
2139     vTemp  = Vec_PtrDup( pNtk->vPis );
2140     vTemp2 = Vec_PtrDup( pNtk->vPos );
2141     vLatch = Vec_PtrAlloc( Abc_NtkLatchNum(pNtk) );
2142     for ( i = 0; i < Abc_NtkLatchNum(pNtk); i++ )
2143     {
2144 //printf( "Setting flop %d to be %d.\n", i, pFlops[i] );
2145         Vec_PtrPush( vTemp,  Abc_NtkCi(pNtk, Abc_NtkPiNum(pNtk) + pFlops[i]) );
2146         Vec_PtrPush( vTemp2, Abc_NtkCo(pNtk, Abc_NtkPoNum(pNtk) + pFlops[i]) );
2147         Vec_PtrPush( vLatch, Abc_NtkBox(pNtk, pFlops[i]) );
2148     }
2149     Vec_PtrFreeP( &pNtk->vCis );
2150     Vec_PtrFreeP( &pNtk->vCos );
2151     Vec_PtrFreeP( &pNtk->vBoxes );
2152     pNtk->vCis   = vTemp;
2153     pNtk->vCos   = vTemp2;
2154     pNtk->vBoxes = vLatch;
2155     // cleanup
2156     Vec_IntFreeP( &pNtk->vObjPerm );
2157 }
2158 
2159 /**Function*************************************************************
2160 
2161   Synopsis    []
2162 
2163   Description []
2164 
2165   SideEffects []
2166 
2167   SeeAlso     []
2168 
2169 ***********************************************************************/
Abc_NtkNodeDup(Abc_Ntk_t * pNtkInit,int nLimit,int fVerbose)2170 Abc_Ntk_t * Abc_NtkNodeDup( Abc_Ntk_t * pNtkInit, int nLimit, int fVerbose )
2171 {
2172     Vec_Ptr_t * vNodes, * vFanouts;
2173     Abc_Ntk_t * pNtk;
2174     Abc_Obj_t * pObj, * pObjNew, * pFanin, * pFanout;
2175     int i, k;
2176     pNtk = Abc_NtkDup( pNtkInit );
2177     vNodes = Vec_PtrAlloc( 100 );
2178     vFanouts = Vec_PtrAlloc( 100 );
2179     do
2180     {
2181         Vec_PtrClear( vNodes );
2182         Abc_NtkForEachNode( pNtk, pObj, i )
2183             if ( Abc_ObjFanoutNum(pObj) >= nLimit )
2184                 Vec_PtrPush( vNodes, pObj );
2185         Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
2186         {
2187             pObjNew = Abc_NtkDupObj( pNtk, pObj, 0 );
2188             Abc_ObjForEachFanin( pObj, pFanin, k )
2189                 Abc_ObjAddFanin( pObjNew, pFanin );
2190             Abc_NodeCollectFanouts( pObj, vFanouts );
2191             Vec_PtrShrink( vFanouts, nLimit / 2 );
2192             Vec_PtrForEachEntry( Abc_Obj_t *, vFanouts, pFanout, k )
2193                 Abc_ObjPatchFanin( pFanout, pObj, pObjNew );
2194         }
2195         if ( fVerbose )
2196             printf( "Duplicated %d nodes.\n", Vec_PtrSize(vNodes) );
2197     }
2198     while ( Vec_PtrSize(vNodes) > 0 );
2199     Vec_PtrFree( vFanouts );
2200     Vec_PtrFree( vNodes );
2201     return pNtk;
2202 }
2203 
2204 /**Function*************************************************************
2205 
2206   Synopsis    []
2207 
2208   Description []
2209 
2210   SideEffects []
2211 
2212   SeeAlso     []
2213 
2214 ***********************************************************************/
Abc_NtkCreateFromSops(char * pName,Vec_Ptr_t * vSops)2215 Abc_Ntk_t * Abc_NtkCreateFromSops( char * pName, Vec_Ptr_t * vSops )
2216 {
2217     int i, k, nObjBeg;
2218     char * pSop = (char *)Vec_PtrEntry(vSops, 0);
2219     Abc_Ntk_t * pNtk = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_SOP, 1 );
2220     pNtk->pName = Extra_UtilStrsav( pName );
2221     for ( k = 0; pSop[k] != ' '; k++ )
2222         Abc_NtkCreatePi( pNtk );
2223     nObjBeg = Abc_NtkObjNumMax(pNtk);
2224     Vec_PtrForEachEntry( char *, vSops, pSop, i )
2225     {
2226         Abc_Obj_t * pObj = Abc_NtkCreateNode( pNtk );
2227         pObj->pData = Abc_SopRegister( (Mem_Flex_t*)pNtk->pManFunc, pSop );
2228         for ( k = 0; pSop[k] != ' '; k++ )
2229             Abc_ObjAddFanin( pObj, Abc_NtkCi(pNtk, k) );
2230     }
2231     for ( i = 0; i < Vec_PtrSize(vSops); i++ )
2232     {
2233         Abc_Obj_t * pObj = Abc_NtkObj( pNtk, nObjBeg + i );
2234         Abc_Obj_t * pObjPo = Abc_NtkCreatePo( pNtk );
2235         Abc_ObjAddFanin( pObjPo, pObj );
2236     }
2237     Abc_NtkAddDummyPiNames( pNtk );
2238     Abc_NtkAddDummyPoNames( pNtk );
2239     return pNtk;
2240 }
2241 
2242 /**Function*************************************************************
2243 
2244   Synopsis    []
2245 
2246   Description []
2247 
2248   SideEffects []
2249 
2250   SeeAlso     []
2251 
2252 ***********************************************************************/
Abc_NtkCreateFromGias(char * pName,Vec_Ptr_t * vGias,Gia_Man_t * pMulti)2253 Abc_Ntk_t * Abc_NtkCreateFromGias( char * pName, Vec_Ptr_t * vGias, Gia_Man_t * pMulti )
2254 {
2255     Gia_Man_t * pGia = pMulti ? pMulti : (Gia_Man_t *)Vec_PtrEntry(vGias, 0);
2256     Abc_Ntk_t * pNtk = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
2257     Abc_Obj_t * pAbcObj, * pAbcObjPo;
2258     Gia_Obj_t * pObj; int i, k;
2259     pNtk->pName = Extra_UtilStrsav( pName );
2260     for ( k = 0; k < Gia_ManCiNum(pGia); k++ )
2261         Abc_NtkCreatePi( pNtk );
2262     if ( pMulti )
2263     {
2264         Gia_ManCleanValue(pGia);
2265         Gia_ManForEachCi( pGia, pObj, k )
2266             pObj->Value = Abc_ObjId( Abc_NtkCi(pNtk, k) );
2267         Gia_ManForEachAnd( pGia, pObj, k )
2268         {
2269             Abc_Obj_t * pAbcObj0 = Abc_NtkObj( pNtk, Gia_ObjFanin0(pObj)->Value );
2270             Abc_Obj_t * pAbcObj1 = Abc_NtkObj( pNtk, Gia_ObjFanin1(pObj)->Value );
2271             pAbcObj0 = Abc_ObjNotCond( pAbcObj0, Gia_ObjFaninC0(pObj) );
2272             pAbcObj1 = Abc_ObjNotCond( pAbcObj1, Gia_ObjFaninC1(pObj) );
2273             pAbcObj  = Abc_AigAnd( (Abc_Aig_t *)pNtk->pManFunc, pAbcObj0, pAbcObj1 );
2274             pObj->Value = Abc_ObjId( pAbcObj );
2275         }
2276         Gia_ManForEachCo( pGia, pObj, k )
2277         {
2278             //pObj = Gia_ManCo(pGia, 0);
2279             if ( Gia_ObjFaninId0p(pGia, pObj) == 0 )
2280                 pAbcObj = Abc_ObjNot( Abc_AigConst1(pNtk) );
2281             else
2282                 pAbcObj = Abc_NtkObj( pNtk, Gia_ObjFanin0(pObj)->Value );
2283             pAbcObj = Abc_ObjNotCond( pAbcObj, Gia_ObjFaninC0(pObj) );
2284             pAbcObjPo = Abc_NtkCreatePo( pNtk );
2285             Abc_ObjAddFanin( pAbcObjPo, pAbcObj );
2286         }
2287     }
2288     else
2289     {
2290     Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
2291     {
2292         assert( Gia_ManCoNum(pGia) == 1 );
2293         Gia_ManCleanValue(pGia);
2294         Gia_ManForEachCi( pGia, pObj, k )
2295             pObj->Value = Abc_ObjId( Abc_NtkCi(pNtk, k) );
2296         Gia_ManForEachAnd( pGia, pObj, k )
2297         {
2298             Abc_Obj_t * pAbcObj0 = Abc_NtkObj( pNtk, Gia_ObjFanin0(pObj)->Value );
2299             Abc_Obj_t * pAbcObj1 = Abc_NtkObj( pNtk, Gia_ObjFanin1(pObj)->Value );
2300             pAbcObj0 = Abc_ObjNotCond( pAbcObj0, Gia_ObjFaninC0(pObj) );
2301             pAbcObj1 = Abc_ObjNotCond( pAbcObj1, Gia_ObjFaninC1(pObj) );
2302             pAbcObj  = Abc_AigAnd( (Abc_Aig_t *)pNtk->pManFunc, pAbcObj0, pAbcObj1 );
2303             pObj->Value = Abc_ObjId( pAbcObj );
2304         }
2305         pObj = Gia_ManCo(pGia, 0);
2306         if ( Gia_ObjFaninId0p(pGia, pObj) == 0 )
2307             pAbcObj = Abc_ObjNot( Abc_AigConst1(pNtk) );
2308         else
2309             pAbcObj = Abc_NtkObj( pNtk, Gia_ObjFanin0(pObj)->Value );
2310         pAbcObj = Abc_ObjNotCond( pAbcObj, Gia_ObjFaninC0(pObj) );
2311         pAbcObjPo = Abc_NtkCreatePo( pNtk );
2312         Abc_ObjAddFanin( pAbcObjPo, pAbcObj );
2313     }
2314     }
2315     Abc_NtkAddDummyPiNames( pNtk );
2316     Abc_NtkAddDummyPoNames( pNtk );
2317     return pNtk;
2318 }
2319 
2320 
2321 ////////////////////////////////////////////////////////////////////////
2322 ///                       END OF FILE                                ///
2323 ////////////////////////////////////////////////////////////////////////
2324 
2325 
2326 ABC_NAMESPACE_IMPL_END
2327 
2328