1 /**CFile****************************************************************
2
3 FileName [abcStrash.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [Network and node package.]
8
9 Synopsis [Strashing of the current network.]
10
11 Author [Alan Mishchenko]
12
13 Affiliation [UC Berkeley]
14
15 Date [Ver. 1.0. Started - June 20, 2005.]
16
17 Revision [$Id: abcStrash.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18
19 ***********************************************************************/
20
21 #include "base/abc/abc.h"
22 #include "bool/dec/dec.h"
23
24 ABC_NAMESPACE_IMPL_START
25
26
27 ////////////////////////////////////////////////////////////////////////
28 /// DECLARATIONS ///
29 ////////////////////////////////////////////////////////////////////////
30
31 static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int fAllNodes, int fRecord );
32
33 ////////////////////////////////////////////////////////////////////////
34 /// FUNCTION DEFINITIONS ///
35 ////////////////////////////////////////////////////////////////////////
36
37 /**Function*************************************************************
38
39 Synopsis [Reapplies structural hashing to the AIG.]
40
41 Description [Because of the structural hashing, this procedure should not
42 change the number of nodes. It is useful to detect the bugs in the original AIG.]
43
44 SideEffects []
45
46 SeeAlso []
47
48 ***********************************************************************/
Abc_NtkRestrash(Abc_Ntk_t * pNtk,int fCleanup)49 Abc_Ntk_t * Abc_NtkRestrash( Abc_Ntk_t * pNtk, int fCleanup )
50 {
51 // extern int timeRetime;
52 Vec_Ptr_t * vNodes;
53 Abc_Ntk_t * pNtkAig;
54 Abc_Obj_t * pObj;
55 int i, nNodes;//, RetValue;
56 assert( Abc_NtkIsStrash(pNtk) );
57 //timeRetime = Abc_Clock();
58 // print warning about choice nodes
59 if ( Abc_NtkGetChoiceNum( pNtk ) )
60 printf( "Warning: The choice nodes in the original AIG are removed by strashing.\n" );
61 // start the new network (constants and CIs of the old network will point to the their counterparts in the new network)
62 pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
63 // restrash the nodes (assuming a topological order of the old network)
64 vNodes = Abc_NtkDfs( pNtk, 0 );
65 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
66 pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkAig->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
67 Vec_PtrFree( vNodes );
68 // finalize the network
69 Abc_NtkFinalize( pNtk, pNtkAig );
70 // print warning about self-feed latches
71 // if ( Abc_NtkCountSelfFeedLatches(pNtkAig) )
72 // printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
73 // perform cleanup if requested
74 if ( fCleanup && (nNodes = Abc_AigCleanup((Abc_Aig_t *)pNtkAig->pManFunc)) )
75 {
76 // printf( "Abc_NtkRestrash(): AIG cleanup removed %d nodes (this is a bug).\n", nNodes );
77 }
78 // duplicate EXDC
79 if ( pNtk->pExdc )
80 pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
81 // make sure everything is okay
82 if ( !Abc_NtkCheck( pNtkAig ) )
83 {
84 printf( "Abc_NtkStrash: The network check has failed.\n" );
85 Abc_NtkDelete( pNtkAig );
86 return NULL;
87 }
88 //timeRetime = Abc_Clock() - timeRetime;
89 // if ( RetValue = Abc_NtkRemoveSelfFeedLatches(pNtkAig) )
90 // printf( "Modified %d self-feeding latches. The result may not verify.\n", RetValue );
91 return pNtkAig;
92
93 }
94
95 /**Function*************************************************************
96
97 Synopsis [Performs structural hashing by generating random number.]
98
99 Description []
100
101 SideEffects []
102
103 SeeAlso []
104
105 ***********************************************************************/
Abc_NtkRestrashRandom_rec(Abc_Ntk_t * pNtk,Abc_Obj_t * pObj)106 void Abc_NtkRestrashRandom_rec( Abc_Ntk_t * pNtk, Abc_Obj_t * pObj )
107 {
108 if ( Abc_NodeIsTravIdCurrent( pObj ) )
109 return;
110 Abc_NodeSetTravIdCurrent( pObj );
111 if ( !Abc_ObjIsNode(pObj) )
112 return;
113 if ( rand() & 1 )
114 {
115 Abc_NtkRestrashRandom_rec( pNtk, Abc_ObjFanin0(pObj) );
116 Abc_NtkRestrashRandom_rec( pNtk, Abc_ObjFanin1(pObj) );
117 }
118 else
119 {
120 Abc_NtkRestrashRandom_rec( pNtk, Abc_ObjFanin1(pObj) );
121 Abc_NtkRestrashRandom_rec( pNtk, Abc_ObjFanin0(pObj) );
122 }
123 pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtk->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
124 }
125
126 /**Function*************************************************************
127
128 Synopsis [Reapplies structural hashing to the AIG.]
129
130 Description [Because of the structural hashing, this procedure should not
131 change the number of nodes. It is useful to detect the bugs in the original AIG.]
132
133 SideEffects []
134
135 SeeAlso []
136
137 ***********************************************************************/
Abc_NtkRestrashRandom(Abc_Ntk_t * pNtk)138 Abc_Ntk_t * Abc_NtkRestrashRandom( Abc_Ntk_t * pNtk )
139 {
140 Abc_Ntk_t * pNtkAig;
141 Abc_Obj_t * pObj;
142 int i;
143 assert( Abc_NtkIsStrash(pNtk) );
144 // print warning about choice nodes
145 if ( Abc_NtkGetChoiceNum( pNtk ) )
146 printf( "Warning: The choice nodes in the original AIG are removed by strashing.\n" );
147 // start the new network (constants and CIs of the old network will point to the their counterparts in the new network)
148 pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
149 // restrash the nodes (assuming a topological order of the old network)
150 Abc_NtkIncrementTravId( pNtk );
151 Abc_NtkForEachCo( pNtk, pObj, i )
152 Abc_NtkRestrashRandom_rec( pNtkAig, Abc_ObjFanin0(pObj) );
153 // finalize the network
154 Abc_NtkFinalize( pNtk, pNtkAig );
155 // duplicate EXDC
156 if ( pNtk->pExdc )
157 pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
158 // make sure everything is okay
159 if ( !Abc_NtkCheck( pNtkAig ) )
160 {
161 printf( "Abc_NtkStrash: The network check has failed.\n" );
162 Abc_NtkDelete( pNtkAig );
163 return NULL;
164 }
165 return pNtkAig;
166
167 }
168
169 /**Function*************************************************************
170
171 Synopsis [Reapplies structural hashing to the AIG.]
172
173 Description [Because of the structural hashing, this procedure should not
174 change the number of nodes. It is useful to detect the bugs in the original AIG.]
175
176 SideEffects []
177
178 SeeAlso []
179
180 ***********************************************************************/
Abc_NtkRestrashZero(Abc_Ntk_t * pNtk,int fCleanup)181 Abc_Ntk_t * Abc_NtkRestrashZero( Abc_Ntk_t * pNtk, int fCleanup )
182 {
183 // extern int timeRetime;
184 Abc_Ntk_t * pNtkAig;
185 Abc_Obj_t * pObj;
186 int i, nNodes;//, RetValue;
187 int Counter = 0;
188 assert( Abc_NtkIsStrash(pNtk) );
189 //timeRetime = Abc_Clock();
190 // print warning about choice nodes
191 if ( Abc_NtkGetChoiceNum( pNtk ) )
192 printf( "Warning: The choice nodes in the original AIG are removed by strashing.\n" );
193 // start the new network (constants and CIs of the old network will point to the their counterparts in the new network)
194 pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
195 // complement the 1-values registers
196 Abc_NtkForEachLatch( pNtk, pObj, i )
197 {
198 if ( Abc_LatchIsInitDc(pObj) )
199 Counter++;
200 else if ( Abc_LatchIsInit1(pObj) )
201 Abc_ObjFanout0(pObj)->pCopy = Abc_ObjNot(Abc_ObjFanout0(pObj)->pCopy);
202 }
203 if ( Counter )
204 printf( "Converting %d flops from don't-care to zero initial value.\n", Counter );
205 // restrash the nodes (assuming a topological order of the old network)
206 Abc_NtkForEachNode( pNtk, pObj, i )
207 pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkAig->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
208 // finalize the network
209 Abc_NtkFinalize( pNtk, pNtkAig );
210 // complement the 1-valued registers
211 Abc_NtkForEachLatch( pNtkAig, pObj, i )
212 if ( Abc_LatchIsInit1(pObj) )
213 {
214 Abc_ObjXorFaninC( Abc_ObjFanin0(pObj), 0 );
215 // if latch has PO as one of its fanouts change latch name
216 if ( Abc_NodeFindCoFanout( Abc_ObjFanout0(pObj) ) )
217 {
218 Nm_ManDeleteIdName( pObj->pNtk->pManName, Abc_ObjFanout0(pObj)->Id );
219 Abc_ObjAssignName( Abc_ObjFanout0(pObj), Abc_ObjName(Abc_ObjFanout0(pObj)), "_inv" );
220 }
221 }
222 // set all constant-0 values
223 Abc_NtkForEachLatch( pNtkAig, pObj, i )
224 Abc_LatchSetInit0( pObj );
225
226 // print warning about self-feed latches
227 // if ( Abc_NtkCountSelfFeedLatches(pNtkAig) )
228 // printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
229 // perform cleanup if requested
230 if ( fCleanup && (nNodes = Abc_AigCleanup((Abc_Aig_t *)pNtkAig->pManFunc)) )
231 printf( "Abc_NtkRestrash(): AIG cleanup removed %d nodes (this is a bug).\n", nNodes );
232 // duplicate EXDC
233 if ( pNtk->pExdc )
234 pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
235 // transfer name IDs
236 if ( pNtk->vNameIds )
237 Abc_NtkTransferNameIds( pNtk, pNtkAig );
238 if ( pNtk->vNameIds )
239 Abc_NtkUpdateNameIds( pNtkAig );
240 // make sure everything is okay
241 if ( !Abc_NtkCheck( pNtkAig ) )
242 {
243 printf( "Abc_NtkStrash: The network check has failed.\n" );
244 Abc_NtkDelete( pNtkAig );
245 return NULL;
246 }
247 //timeRetime = Abc_Clock() - timeRetime;
248 // if ( RetValue = Abc_NtkRemoveSelfFeedLatches(pNtkAig) )
249 // printf( "Modified %d self-feeding latches. The result may not verify.\n", RetValue );
250 return pNtkAig;
251
252 }
253
254 /**Function*************************************************************
255
256 Synopsis [Transforms logic network into structurally hashed AIG.]
257
258 Description []
259
260 SideEffects []
261
262 SeeAlso []
263
264 ***********************************************************************/
Abc_NtkStrash(Abc_Ntk_t * pNtk,int fAllNodes,int fCleanup,int fRecord)265 Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, int fAllNodes, int fCleanup, int fRecord )
266 {
267 Abc_Ntk_t * pNtkAig;
268 int nNodes;
269 assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) );
270 // consider the special case when the network is already structurally hashed
271 if ( Abc_NtkIsStrash(pNtk) )
272 return Abc_NtkRestrash( pNtk, fCleanup );
273 // convert the node representation in the logic network to the AIG form
274 if ( !Abc_NtkToAig(pNtk) )
275 {
276 printf( "Converting to AIGs has failed.\n" );
277 return NULL;
278 }
279 // perform strashing
280 // Abc_NtkCleanCopy( pNtk );
281 pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
282 Abc_NtkStrashPerform( pNtk, pNtkAig, fAllNodes, fRecord );
283 Abc_NtkFinalize( pNtk, pNtkAig );
284 // transfer name IDs
285 if ( pNtk->vNameIds )
286 Abc_NtkTransferNameIds( pNtk, pNtkAig );
287 // print warning about self-feed latches
288 // if ( Abc_NtkCountSelfFeedLatches(pNtkAig) )
289 // printf( "Warning: The network has %d self-feeding latches.\n", Abc_NtkCountSelfFeedLatches(pNtkAig) );
290 // perform cleanup if requested
291 nNodes = fCleanup? Abc_AigCleanup((Abc_Aig_t *)pNtkAig->pManFunc) : 0;
292 // if ( nNodes )
293 // printf( "Warning: AIG cleanup removed %d nodes (this is not a bug).\n", nNodes );
294 // duplicate EXDC
295 if ( pNtk->pExdc )
296 pNtkAig->pExdc = Abc_NtkStrash( pNtk->pExdc, fAllNodes, fCleanup, fRecord );
297 // make sure everything is okay
298 if ( !Abc_NtkCheck( pNtkAig ) )
299 {
300 printf( "Abc_NtkStrash: The network check has failed.\n" );
301 Abc_NtkDelete( pNtkAig );
302 return NULL;
303 }
304 return pNtkAig;
305 }
306
307 /**Function*************************************************************
308
309 Synopsis [Appends the second network to the first.]
310
311 Description [Modifies the first network by adding the logic of the second.
312 Performs structural hashing while appending the networks. Does not change
313 the second network. Returns 0 if the appending failed, 1 otherise.]
314
315 SideEffects []
316
317 SeeAlso []
318
319 ***********************************************************************/
Abc_NtkAppend(Abc_Ntk_t * pNtk1,Abc_Ntk_t * pNtk2,int fAddPos)320 int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos )
321 {
322 Abc_Obj_t * pObj;
323 char * pName;
324 int i, nNewCis;
325 // the first network should be an AIG
326 assert( Abc_NtkIsStrash(pNtk1) );
327 assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) );
328 if ( Abc_NtkIsLogic(pNtk2) && !Abc_NtkToAig(pNtk2) )
329 {
330 printf( "Converting to AIGs has failed.\n" );
331 return 0;
332 }
333 // check that the networks have the same PIs
334 // reorder PIs of pNtk2 according to pNtk1
335 if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1, 1 ) )
336 printf( "Abc_NtkAppend(): The union of the network PIs is computed (warning).\n" );
337 // perform strashing
338 nNewCis = 0;
339 Abc_NtkCleanCopy( pNtk2 );
340 if ( Abc_NtkIsStrash(pNtk2) )
341 Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtk1);
342 Abc_NtkForEachCi( pNtk2, pObj, i )
343 {
344 pName = Abc_ObjName(pObj);
345 pObj->pCopy = Abc_NtkFindCi(pNtk1, Abc_ObjName(pObj));
346 if ( pObj->pCopy == NULL )
347 {
348 pObj->pCopy = Abc_NtkDupObj(pNtk1, pObj, 1);
349 nNewCis++;
350 }
351 }
352 if ( nNewCis )
353 printf( "Warning: Procedure Abc_NtkAppend() added %d new CIs.\n", nNewCis );
354 // add pNtk2 to pNtk1 while strashing
355 if ( Abc_NtkIsLogic(pNtk2) )
356 Abc_NtkStrashPerform( pNtk2, pNtk1, 1, 0 );
357 else
358 Abc_NtkForEachNode( pNtk2, pObj, i )
359 pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtk1->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
360 // add the COs of the second network
361 if ( fAddPos )
362 {
363 Abc_NtkForEachPo( pNtk2, pObj, i )
364 {
365 Abc_NtkDupObj( pNtk1, pObj, 0 );
366 Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) );
367 Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj), NULL );
368 }
369 }
370 else
371 {
372 Abc_Obj_t * pObjOld, * pDriverOld, * pDriverNew;
373 int fCompl, iNodeId;
374 // OR the choices
375 Abc_NtkForEachCo( pNtk2, pObj, i )
376 {
377 iNodeId = Nm_ManFindIdByNameTwoTypes( pNtk1->pManName, Abc_ObjName(pObj), ABC_OBJ_PO, ABC_OBJ_BI );
378 // if ( iNodeId < 0 )
379 // continue;
380 assert( iNodeId >= 0 );
381 pObjOld = Abc_NtkObj( pNtk1, iNodeId );
382 // derive the new driver
383 pDriverOld = Abc_ObjChild0( pObjOld );
384 pDriverNew = Abc_ObjChild0Copy( pObj );
385 pDriverNew = Abc_AigOr( (Abc_Aig_t *)pNtk1->pManFunc, pDriverOld, pDriverNew );
386 if ( Abc_ObjRegular(pDriverOld) == Abc_ObjRegular(pDriverNew) )
387 continue;
388 // replace the old driver by the new driver
389 fCompl = Abc_ObjRegular(pDriverOld)->fPhase ^ Abc_ObjRegular(pDriverNew)->fPhase;
390 Abc_ObjPatchFanin( pObjOld, Abc_ObjRegular(pDriverOld), Abc_ObjNotCond(Abc_ObjRegular(pDriverNew), fCompl) );
391 }
392 }
393 // make sure that everything is okay
394 if ( !Abc_NtkCheck( pNtk1 ) )
395 {
396 printf( "Abc_NtkAppend: The network check has failed.\n" );
397 return 0;
398 }
399 return 1;
400 }
401
402 /**Function*************************************************************
403
404 Synopsis [Prepares the network for strashing.]
405
406 Description []
407
408 SideEffects []
409
410 SeeAlso []
411
412 ***********************************************************************/
Abc_NtkStrashPerform(Abc_Ntk_t * pNtkOld,Abc_Ntk_t * pNtkNew,int fAllNodes,int fRecord)413 void Abc_NtkStrashPerform( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew, int fAllNodes, int fRecord )
414 {
415 Vec_Ptr_t * vNodes;
416 Abc_Obj_t * pNodeOld;
417 int i; //, clk = Abc_Clock();
418 assert( Abc_NtkIsLogic(pNtkOld) );
419 assert( Abc_NtkIsStrash(pNtkNew) );
420 // vNodes = Abc_NtkDfs( pNtkOld, fAllNodes );
421 vNodes = Abc_NtkDfsIter( pNtkOld, fAllNodes );
422 //printf( "Nodes = %d. ", Vec_PtrSize(vNodes) );
423 //ABC_PRT( "Time", Abc_Clock() - clk );
424 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pNodeOld, i )
425 {
426 if ( Abc_ObjIsBarBuf(pNodeOld) )
427 pNodeOld->pCopy = Abc_ObjChild0Copy(pNodeOld);
428 else
429 pNodeOld->pCopy = Abc_NodeStrash( pNtkNew, pNodeOld, fRecord );
430 }
431 Vec_PtrFree( vNodes );
432 }
433
434 /**Function*************************************************************
435
436 Synopsis [Transfers the AIG from one manager into another.]
437
438 Description []
439
440 SideEffects []
441
442 SeeAlso []
443
444 ***********************************************************************/
Abc_NodeStrash_rec(Abc_Aig_t * pMan,Hop_Obj_t * pObj)445 void Abc_NodeStrash_rec( Abc_Aig_t * pMan, Hop_Obj_t * pObj )
446 {
447 assert( !Hop_IsComplement(pObj) );
448 if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
449 return;
450 Abc_NodeStrash_rec( pMan, Hop_ObjFanin0(pObj) );
451 Abc_NodeStrash_rec( pMan, Hop_ObjFanin1(pObj) );
452 pObj->pData = Abc_AigAnd( pMan, (Abc_Obj_t *)Hop_ObjChild0Copy(pObj), (Abc_Obj_t *)Hop_ObjChild1Copy(pObj) );
453 assert( !Hop_ObjIsMarkA(pObj) ); // loop detection
454 Hop_ObjSetMarkA( pObj );
455 }
456
457 /**Function*************************************************************
458
459 Synopsis [Strashes one logic node.]
460
461 Description [Assume the network is in the AIG form]
462
463 SideEffects []
464
465 SeeAlso []
466
467 ***********************************************************************/
Abc_NodeStrash(Abc_Ntk_t * pNtkNew,Abc_Obj_t * pNodeOld,int fRecord)468 Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, int fRecord )
469 {
470 Hop_Man_t * pMan;
471 Hop_Obj_t * pRoot;
472 Abc_Obj_t * pFanin;
473 int i;
474 assert( Abc_ObjIsNode(pNodeOld) );
475 assert( Abc_NtkHasAig(pNodeOld->pNtk) && !Abc_NtkIsStrash(pNodeOld->pNtk) );
476 // get the local AIG manager and the local root node
477 pMan = (Hop_Man_t *)pNodeOld->pNtk->pManFunc;
478 pRoot = (Hop_Obj_t *)pNodeOld->pData;
479 // check the constant case
480 if ( Abc_NodeIsConst(pNodeOld) || Hop_Regular(pRoot) == Hop_ManConst1(pMan) )
481 return Abc_ObjNotCond( Abc_AigConst1(pNtkNew), Hop_IsComplement(pRoot) );
482 // perform special case-strashing using the record of AIG subgraphs
483 /*
484 if ( fRecord && Abc_NtkRecIsRunning() && Abc_ObjFaninNum(pNodeOld) > 2 && Abc_ObjFaninNum(pNodeOld) <= Abc_NtkRecVarNum() )
485 {
486 extern Vec_Int_t * Abc_NtkRecMemory();
487 extern int Abc_NtkRecStrashNode( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, unsigned * pTruth, int nVars );
488 int nVars = Abc_NtkRecVarNum();
489 Vec_Int_t * vMemory = Abc_NtkRecMemory();
490 unsigned * pTruth = Hop_ManConvertAigToTruth( pMan, Hop_Regular(pRoot), nVars, vMemory, 0 );
491 assert( Extra_TruthSupportSize(pTruth, nVars) == Abc_ObjFaninNum(pNodeOld) ); // should be swept
492 if ( Hop_IsComplement(pRoot) )
493 Extra_TruthNot( pTruth, pTruth, nVars );
494 if ( Abc_NtkRecStrashNode( pNtkNew, pNodeOld, pTruth, nVars ) )
495 return pNodeOld->pCopy;
496 }
497 */
498 // set elementary variables
499 Abc_ObjForEachFanin( pNodeOld, pFanin, i )
500 Hop_IthVar(pMan, i)->pData = pFanin->pCopy;
501 // strash the AIG of this node
502 Abc_NodeStrash_rec( (Abc_Aig_t *)pNtkNew->pManFunc, Hop_Regular(pRoot) );
503 Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
504 // return the final node
505 return Abc_ObjNotCond( (Abc_Obj_t *)Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
506 }
507
508
509
510
511
512
513
514 /**Function*************************************************************
515
516 Synopsis [Copies the topmost levels of the network.]
517
518 Description []
519
520 SideEffects []
521
522 SeeAlso []
523
524 ***********************************************************************/
Abc_NtkTopmost_rec(Abc_Ntk_t * pNtkNew,Abc_Obj_t * pNode,int LevelCut)525 Abc_Obj_t * Abc_NtkTopmost_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int LevelCut )
526 {
527 assert( !Abc_ObjIsComplement(pNode) );
528 if ( pNode->pCopy )
529 return pNode->pCopy;
530 if ( pNode->Level <= (unsigned)LevelCut )
531 return pNode->pCopy = Abc_NtkCreatePi( pNtkNew );
532 Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(pNode), LevelCut );
533 Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin1(pNode), LevelCut );
534 return pNode->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
535 }
536
537 /**Function*************************************************************
538
539 Synopsis [Copies the topmost levels of the network.]
540
541 Description []
542
543 SideEffects []
544
545 SeeAlso []
546
547 ***********************************************************************/
Abc_NtkTopmost(Abc_Ntk_t * pNtk,int nLevels)548 Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels )
549 {
550 Abc_Ntk_t * pNtkNew;
551 Abc_Obj_t * pObjNew, * pObjPo;
552 int LevelCut;
553 assert( Abc_NtkIsStrash(pNtk) );
554 assert( Abc_NtkCoNum(pNtk) == 1 );
555 // get the cutoff level
556 LevelCut = Abc_MaxInt( 0, Abc_AigLevel(pNtk) - nLevels );
557 // start the network
558 pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
559 pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
560 Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
561 // create PIs below the cut and nodes above the cut
562 Abc_NtkCleanCopy( pNtk );
563 pObjNew = Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(Abc_NtkPo(pNtk, 0)), LevelCut );
564 pObjNew = Abc_ObjNotCond( pObjNew, Abc_ObjFaninC0(Abc_NtkPo(pNtk, 0)) );
565 // add the PO node and name
566 pObjPo = Abc_NtkCreatePo(pNtkNew);
567 Abc_ObjAddFanin( pObjPo, pObjNew );
568 Abc_NtkAddDummyPiNames( pNtkNew );
569 Abc_ObjAssignName( pObjPo, Abc_ObjName(Abc_NtkPo(pNtk, 0)), NULL );
570 // make sure everything is okay
571 if ( !Abc_NtkCheck( pNtkNew ) )
572 {
573 printf( "Abc_NtkTopmost: The network check has failed.\n" );
574 Abc_NtkDelete( pNtkNew );
575 return NULL;
576 }
577 return pNtkNew;
578 }
579
580
581
582 /**Function*************************************************************
583
584 Synopsis [Comparison procedure for two integers.]
585
586 Description []
587
588 SideEffects []
589
590 SeeAlso []
591
592 ***********************************************************************/
Vec_CompareNodeIds(Abc_Obj_t ** pp1,Abc_Obj_t ** pp2)593 static int Vec_CompareNodeIds( Abc_Obj_t ** pp1, Abc_Obj_t ** pp2 )
594 {
595 if ( Abc_ObjRegular(*pp1)->Id < Abc_ObjRegular(*pp2)->Id )
596 return -1;
597 if ( Abc_ObjRegular(*pp1)->Id > Abc_ObjRegular(*pp2)->Id ) //
598 return 1;
599 return 0;
600 }
601
602 /**Function*************************************************************
603
604 Synopsis [Collects the large supergate.]
605
606 Description []
607
608 SideEffects []
609
610 SeeAlso []
611
612 ***********************************************************************/
Abc_NodeGetSuper(Abc_Obj_t * pNode)613 Vec_Ptr_t * Abc_NodeGetSuper( Abc_Obj_t * pNode )
614 {
615 Vec_Ptr_t * vSuper, * vFront;
616 Abc_Obj_t * pAnd, * pFanin;
617 int i;
618 assert( Abc_ObjIsNode(pNode) && !Abc_ObjIsComplement(pNode) );
619 vSuper = Vec_PtrAlloc( 100 );
620 // explore the frontier
621 vFront = Vec_PtrAlloc( 100 );
622 Vec_PtrPush( vFront, pNode );
623 Vec_PtrForEachEntry( Abc_Obj_t *, vFront, pAnd, i )
624 {
625 pFanin = Abc_ObjChild0(pAnd);
626 if ( Abc_ObjIsNode(pFanin) && !Abc_ObjIsComplement(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
627 Vec_PtrPush( vFront, pFanin );
628 else
629 Vec_PtrPush( vSuper, pFanin );
630
631 pFanin = Abc_ObjChild1(pAnd);
632 if ( Abc_ObjIsNode(pFanin) && !Abc_ObjIsComplement(pFanin) && Abc_ObjFanoutNum(pFanin) == 1 )
633 Vec_PtrPush( vFront, pFanin );
634 else
635 Vec_PtrPush( vSuper, pFanin );
636 }
637 Vec_PtrFree( vFront );
638 // reverse the array of pointers to start with lower IDs
639 vFront = Vec_PtrAlloc( Vec_PtrSize(vSuper) );
640 Vec_PtrForEachEntryReverse( Abc_Obj_t *, vSuper, pNode, i )
641 Vec_PtrPush( vFront, pNode );
642 Vec_PtrFree( vSuper );
643 vSuper = vFront;
644 // uniquify and return the frontier
645 Vec_PtrUniqify( vSuper, (int (*)())Vec_CompareNodeIds );
646 return vSuper;
647 }
648
649 /**Function*************************************************************
650
651 Synopsis [Copies the topmost levels of the network.]
652
653 Description []
654
655 SideEffects []
656
657 SeeAlso []
658
659 ***********************************************************************/
Abc_NtkTopAnd(Abc_Ntk_t * pNtk)660 Abc_Ntk_t * Abc_NtkTopAnd( Abc_Ntk_t * pNtk )
661 {
662 Vec_Ptr_t * vNodes, * vOrder;
663 Abc_Ntk_t * pNtkAig;
664 Abc_Obj_t * pObj, * pDriver, * pObjPo;
665 int i, nNodes;
666 assert( Abc_NtkIsStrash(pNtk) );
667 // get the first PO
668 pObjPo = Abc_NtkPo(pNtk, 0);
669 vNodes = Abc_NodeGetSuper( Abc_ObjChild0(pObjPo) );
670 assert( Vec_PtrSize(vNodes) >= 2 );
671 // start the new network (constants and CIs of the old network will point to the their counterparts in the new network)
672 Abc_NtkCleanCopy( pNtk );
673 pNtkAig = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
674 pNtkAig->pName = Extra_UtilStrsav(pNtk->pName);
675 pNtkAig->pSpec = Extra_UtilStrsav(pNtk->pSpec);
676 Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkAig);
677 Abc_NtkForEachPi( pNtk, pObj, i )
678 Abc_NtkDupObj( pNtkAig, pObj, 1 );
679 // restrash the nodes reachable from the roots
680 vOrder = Abc_NtkDfsIterNodes( pNtk, vNodes );
681 Vec_PtrForEachEntry( Abc_Obj_t *, vOrder, pObj, i )
682 pObj->pCopy = Abc_AigAnd( (Abc_Aig_t *)pNtkAig->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
683 Vec_PtrFree( vOrder );
684 // finalize the network
685 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
686 {
687 pObjPo = Abc_NtkCreatePo(pNtkAig);
688 pDriver = Abc_ObjNotCond(Abc_ObjRegular(pObj)->pCopy, Abc_ObjIsComplement(pObj));
689 Abc_ObjAddFanin( pObjPo, pDriver );
690 Abc_ObjAssignName( pObjPo, Abc_ObjName(pObjPo), NULL );
691 }
692 Vec_PtrFree( vNodes );
693 // perform cleanup if requested
694 if ( (nNodes = Abc_AigCleanup((Abc_Aig_t *)pNtkAig->pManFunc)) )
695 printf( "Abc_NtkTopAnd(): AIG cleanup removed %d nodes (this is a bug).\n", nNodes );
696 // make sure everything is okay
697 if ( !Abc_NtkCheck( pNtkAig ) )
698 {
699 printf( "Abc_NtkStrash: The network check has failed.\n" );
700 Abc_NtkDelete( pNtkAig );
701 return NULL;
702 }
703 return pNtkAig;
704 }
705
706 /**Function*************************************************************
707
708 Synopsis [Writes the AIG into a file for parsing.]
709
710 Description [Ordering: c0, pis, ands, pos. ]
711
712 SideEffects []
713
714 SeeAlso []
715
716 ***********************************************************************/
Abc_NtkWriteAig(Abc_Ntk_t * pNtk,char * pFileName)717 void Abc_NtkWriteAig( Abc_Ntk_t * pNtk, char * pFileName )
718 {
719 FILE * pFile;
720 Vec_Int_t * vId2Num;
721 Abc_Obj_t * pObj;
722 int i, iLit;
723 assert( Abc_NtkIsStrash(pNtk) );
724 assert( Abc_NtkLatchNum(pNtk) == 0 );
725 if ( pFileName == NULL )
726 pFile = stdout;
727 else
728 pFile = fopen( pFileName, "w" );
729 if ( pFile == NULL )
730 {
731 printf( "Cannot open output file.\n" );
732 return;
733 }
734 vId2Num = Vec_IntAlloc( 2*Abc_NtkObjNumMax(pNtk) );
735 Vec_IntFill( vId2Num, 2*Abc_NtkObjNumMax(pNtk), -1 );
736
737 iLit = 0;
738 Vec_IntWriteEntry( vId2Num, 2*Abc_ObjId(Abc_AigConst1(pNtk))+1, iLit++ );
739 Vec_IntWriteEntry( vId2Num, 2*Abc_ObjId(Abc_AigConst1(pNtk))+0, iLit++ );
740 Abc_NtkForEachPi( pNtk, pObj, i )
741 {
742 Vec_IntWriteEntry( vId2Num, 2*Abc_ObjId(pObj)+0, iLit++ );
743 Vec_IntWriteEntry( vId2Num, 2*Abc_ObjId(pObj)+1, iLit++ );
744 }
745 Abc_AigForEachAnd( pNtk, pObj, i )
746 {
747 Vec_IntWriteEntry( vId2Num, 2*Abc_ObjId(pObj)+0, iLit++ );
748 Vec_IntWriteEntry( vId2Num, 2*Abc_ObjId(pObj)+1, iLit++ );
749 }
750 fprintf( pFile, "{\n" );
751 fprintf( pFile, " \"%s\", ", Abc_NtkName(pNtk) );
752 fprintf( pFile, "// pi=%d po=%d and=%d", Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk), Abc_NtkNodeNum(pNtk) );
753 fprintf( pFile, "\n" );
754 fprintf( pFile, " { " );
755 Abc_NtkForEachPi( pNtk, pObj, i )
756 fprintf( pFile, "\"%s\",", Abc_ObjName(pObj) );
757 fprintf( pFile, "NULL },\n" );
758 fprintf( pFile, " { " );
759 Abc_NtkForEachPo( pNtk, pObj, i )
760 fprintf( pFile, "\"%s\",", Abc_ObjName(pObj) );
761 fprintf( pFile, "NULL },\n" );
762 fprintf( pFile, " { " );
763 Abc_AigForEachAnd( pNtk, pObj, i )
764 fprintf( pFile, "%d,", Vec_IntEntry(vId2Num, 2*Abc_ObjFaninId0(pObj) + Abc_ObjFaninC0(pObj)) );
765 fprintf( pFile, "0 },\n" );
766 fprintf( pFile, " { " );
767 Abc_AigForEachAnd( pNtk, pObj, i )
768 fprintf( pFile, "%d,", Vec_IntEntry(vId2Num, 2*Abc_ObjFaninId1(pObj) + Abc_ObjFaninC1(pObj)) );
769 fprintf( pFile, "0 },\n" );
770 fprintf( pFile, " { " );
771 Abc_NtkForEachPo( pNtk, pObj, i )
772 fprintf( pFile, "%d,", Vec_IntEntry(vId2Num, 2*Abc_ObjFaninId0(pObj) + Abc_ObjFaninC0(pObj)) );
773 fprintf( pFile, "0 },\n" );
774 fprintf( pFile, "},\n" );
775 if ( pFile != stdout )
776 fclose( pFile );
777 Vec_IntFree( vId2Num );
778 }
779
780 /**Function*************************************************************
781
782 Synopsis []
783
784 Description []
785
786 SideEffects []
787
788 SeeAlso []
789
790 ***********************************************************************/
Abc_NtkPutOnTop(Abc_Ntk_t * pNtk,Abc_Ntk_t * pNtk2)791 Abc_Ntk_t * Abc_NtkPutOnTop( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtk2 )
792 {
793 Vec_Ptr_t * vNodes;
794 Abc_Ntk_t * pNtkNew;
795 Abc_Obj_t * pObj, * pFanin;
796 int i, k;
797 assert( Abc_NtkIsLogic(pNtk) );
798 assert( Abc_NtkIsLogic(pNtk2) );
799 assert( Abc_NtkPoNum(pNtk) == Abc_NtkPiNum(pNtk2) );
800 // clean the node copy fields
801 Abc_NtkCleanCopy( pNtk );
802 Abc_NtkCleanCopy( pNtk2 );
803 // duplicate the name and the spec
804 pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
805 pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
806 pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
807 // clone CIs/CIs/boxes
808 Abc_NtkForEachPi( pNtk, pObj, i )
809 Abc_NtkDupObj( pNtkNew, pObj, 1 );
810 // add internal nodes
811 vNodes = Abc_NtkDfs( pNtk, 0 );
812 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
813 {
814 Abc_NtkDupObj( pNtkNew, pObj, 0 );
815 Abc_ObjForEachFanin( pObj, pFanin, k )
816 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
817 }
818 Vec_PtrFree( vNodes );
819 // transfer to the POs
820 Abc_NtkForEachPi( pNtk2, pObj, i )
821 pObj->pCopy = Abc_ObjChild0Copy( Abc_NtkPo(pNtk, i) );
822 // add internal nodes
823 vNodes = Abc_NtkDfs( pNtk2, 0 );
824 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
825 {
826 Abc_NtkDupObj( pNtkNew, pObj, 0 );
827 Abc_ObjForEachFanin( pObj, pFanin, k )
828 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
829 }
830 Vec_PtrFree( vNodes );
831 // clone CIs/CIs/boxes
832 Abc_NtkForEachPo( pNtk2, pObj, i )
833 {
834 Abc_NtkDupObj( pNtkNew, pObj, 1 );
835 Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) );
836 }
837 if ( !Abc_NtkCheck( pNtkNew ) )
838 fprintf( stdout, "Abc_NtkPutOnTop(): Network check has failed.\n" );
839 return pNtkNew;
840 }
841
842 ////////////////////////////////////////////////////////////////////////
843 /// END OF FILE ///
844 ////////////////////////////////////////////////////////////////////////
845
846
847 ABC_NAMESPACE_IMPL_END
848
849