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