1 /**CFile****************************************************************
2 
3   FileName    [abcObj.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Network and node package.]
8 
9   Synopsis    [Object 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: abcObj.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 
26 #ifdef ABC_USE_CUDD
27 #include "bdd/extrab/extraBdd.h"
28 #endif
29 
30 ABC_NAMESPACE_IMPL_START
31 
32 
33 ////////////////////////////////////////////////////////////////////////
34 ///                        DECLARATIONS                              ///
35 ////////////////////////////////////////////////////////////////////////
36 
37 ////////////////////////////////////////////////////////////////////////
38 ///                     FUNCTION DEFINITIONS                         ///
39 ////////////////////////////////////////////////////////////////////////
40 
41 /**Function*************************************************************
42 
43   Synopsis    [Creates a new object.]
44 
45   Description []
46 
47   SideEffects []
48 
49   SeeAlso     []
50 
51 ***********************************************************************/
Abc_ObjAlloc(Abc_Ntk_t * pNtk,Abc_ObjType_t Type)52 Abc_Obj_t * Abc_ObjAlloc( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
53 {
54     Abc_Obj_t * pObj;
55     if ( pNtk->pMmObj )
56         pObj = (Abc_Obj_t *)Mem_FixedEntryFetch( pNtk->pMmObj );
57     else
58         pObj = (Abc_Obj_t *)ABC_ALLOC( Abc_Obj_t, 1 );
59     memset( pObj, 0, sizeof(Abc_Obj_t) );
60     pObj->pNtk = pNtk;
61     pObj->Type = Type;
62     pObj->Id   = -1;
63     return pObj;
64 }
65 
66 /**Function*************************************************************
67 
68   Synopsis    [Recycles the object.]
69 
70   Description []
71 
72   SideEffects []
73 
74   SeeAlso     []
75 
76 ***********************************************************************/
Abc_ObjRecycle(Abc_Obj_t * pObj)77 void Abc_ObjRecycle( Abc_Obj_t * pObj )
78 {
79     Abc_Ntk_t * pNtk = pObj->pNtk;
80 //    int LargePiece = (4 << ABC_NUM_STEPS);
81     // free large fanout arrays
82 //    if ( pNtk->pMmStep && pObj->vFanouts.nCap * 4 > LargePiece )
83 //        free( pObj->vFanouts.pArray );
84     if ( pNtk->pMmStep == NULL )
85     {
86         ABC_FREE( pObj->vFanouts.pArray );
87         ABC_FREE( pObj->vFanins.pArray );
88     }
89     // clean the memory to make deleted object distinct from the live one
90     memset( pObj, 0, sizeof(Abc_Obj_t) );
91     // recycle the object
92     if ( pNtk->pMmObj )
93         Mem_FixedEntryRecycle( pNtk->pMmObj, (char *)pObj );
94     else
95         ABC_FREE( pObj );
96 }
97 
98 /**Function*************************************************************
99 
100   Synopsis    [Adds the node to the network.]
101 
102   Description []
103 
104   SideEffects []
105 
106   SeeAlso     []
107 
108 ***********************************************************************/
Abc_NtkCreateObj(Abc_Ntk_t * pNtk,Abc_ObjType_t Type)109 Abc_Obj_t * Abc_NtkCreateObj( Abc_Ntk_t * pNtk, Abc_ObjType_t Type )
110 {
111     Abc_Obj_t * pObj;
112     // create new object, assign ID, and add to the array
113     pObj = Abc_ObjAlloc( pNtk, Type );
114     pObj->Id = pNtk->vObjs->nSize;
115     Vec_PtrPush( pNtk->vObjs, pObj );
116     pNtk->nObjCounts[Type]++;
117     pNtk->nObjs++;
118     // perform specialized operations depending on the object type
119     switch (Type)
120     {
121         case ABC_OBJ_NONE:
122             assert(0);
123             break;
124         case ABC_OBJ_CONST1:
125             assert(0);
126             break;
127         case ABC_OBJ_PI:
128 //            pObj->iTemp = Vec_PtrSize(pNtk->vCis);
129             Vec_PtrPush( pNtk->vPis, pObj );
130             Vec_PtrPush( pNtk->vCis, pObj );
131             break;
132         case ABC_OBJ_PO:
133 //            pObj->iTemp = Vec_PtrSize(pNtk->vCos);
134             Vec_PtrPush( pNtk->vPos, pObj );
135             Vec_PtrPush( pNtk->vCos, pObj );
136             break;
137         case ABC_OBJ_BI:
138             if ( pNtk->vCos ) Vec_PtrPush( pNtk->vCos, pObj );
139             break;
140         case ABC_OBJ_BO:
141             if ( pNtk->vCis ) Vec_PtrPush( pNtk->vCis, pObj );
142             break;
143         case ABC_OBJ_NET:
144         case ABC_OBJ_NODE:
145             break;
146         case ABC_OBJ_LATCH:
147             pObj->pData = (void *)ABC_INIT_NONE;
148         case ABC_OBJ_WHITEBOX:
149         case ABC_OBJ_BLACKBOX:
150             if ( pNtk->vBoxes ) Vec_PtrPush( pNtk->vBoxes, pObj );
151             break;
152         default:
153             assert(0);
154             break;
155     }
156     return pObj;
157 }
158 
159 /**Function*************************************************************
160 
161   Synopsis    [Deletes the object from the network.]
162 
163   Description []
164 
165   SideEffects []
166 
167   SeeAlso     []
168 
169 ***********************************************************************/
Abc_NtkDeleteObj(Abc_Obj_t * pObj)170 void Abc_NtkDeleteObj( Abc_Obj_t * pObj )
171 {
172     Abc_Ntk_t * pNtk = pObj->pNtk;
173     Vec_Ptr_t * vNodes;
174     int i;
175     assert( !Abc_ObjIsComplement(pObj) );
176     // remove from the table of names
177     if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) )
178         Nm_ManDeleteIdName(pObj->pNtk->pManName, pObj->Id);
179     // delete fanins and fanouts
180     vNodes = Vec_PtrAlloc( 100 );
181     Abc_NodeCollectFanouts( pObj, vNodes );
182     for ( i = 0; i < vNodes->nSize; i++ )
183         Abc_ObjDeleteFanin( (Abc_Obj_t *)vNodes->pArray[i], pObj );
184     Abc_NodeCollectFanins( pObj, vNodes );
185     for ( i = 0; i < vNodes->nSize; i++ )
186         Abc_ObjDeleteFanin( pObj, (Abc_Obj_t *)vNodes->pArray[i] );
187     Vec_PtrFree( vNodes );
188     // remove from the list of objects
189     Vec_PtrWriteEntry( pNtk->vObjs, pObj->Id, NULL );
190     pObj->Id = (1<<26)-1;
191     pNtk->nObjCounts[pObj->Type]--;
192     pNtk->nObjs--;
193     // perform specialized operations depending on the object type
194     switch (pObj->Type)
195     {
196         case ABC_OBJ_NONE:
197             assert(0);
198             break;
199         case ABC_OBJ_CONST1:
200             assert(0);
201             break;
202         case ABC_OBJ_PI:
203             Vec_PtrRemove( pNtk->vPis, pObj );
204             Vec_PtrRemove( pNtk->vCis, pObj );
205             break;
206         case ABC_OBJ_PO:
207             Vec_PtrRemove( pNtk->vPos, pObj );
208             Vec_PtrRemove( pNtk->vCos, pObj );
209             break;
210         case ABC_OBJ_BI:
211             if ( pNtk->vCos ) Vec_PtrRemove( pNtk->vCos, pObj );
212             break;
213         case ABC_OBJ_BO:
214             if ( pNtk->vCis ) Vec_PtrRemove( pNtk->vCis, pObj );
215             break;
216         case ABC_OBJ_NET:
217             break;
218         case ABC_OBJ_NODE:
219 #ifdef ABC_USE_CUDD
220             if ( Abc_NtkHasBdd(pNtk) )
221                 Cudd_RecursiveDeref( (DdManager *)pNtk->pManFunc, (DdNode *)pObj->pData );
222 #endif
223             pObj->pData = NULL;
224             break;
225         case ABC_OBJ_LATCH:
226         case ABC_OBJ_WHITEBOX:
227         case ABC_OBJ_BLACKBOX:
228             if ( pNtk->vBoxes ) Vec_PtrRemove( pNtk->vBoxes, pObj );
229             break;
230         default:
231             assert(0);
232             break;
233     }
234     // recycle the object memory
235     Abc_ObjRecycle( pObj );
236 }
237 
238 /**Function*************************************************************
239 
240   Synopsis    [Deletes the PO from the network.]
241 
242   Description []
243 
244   SideEffects []
245 
246   SeeAlso     []
247 
248 ***********************************************************************/
Abc_NtkDeleteObjPo(Abc_Obj_t * pObj)249 void Abc_NtkDeleteObjPo( Abc_Obj_t * pObj )
250 {
251     assert( Abc_ObjIsPo(pObj) );
252     // remove from the table of names
253     if ( Nm_ManFindNameById(pObj->pNtk->pManName, pObj->Id) )
254         Nm_ManDeleteIdName(pObj->pNtk->pManName, pObj->Id);
255     // delete fanins
256     Abc_ObjDeleteFanin( pObj, Abc_ObjFanin0(pObj) );
257     // remove from the list of objects
258     Vec_PtrWriteEntry( pObj->pNtk->vObjs, pObj->Id, NULL );
259     pObj->Id = (1<<26)-1;
260     pObj->pNtk->nObjCounts[pObj->Type]--;
261     pObj->pNtk->nObjs--;
262     // recycle the object memory
263     Abc_ObjRecycle( pObj );
264 }
265 
266 
267 /**Function*************************************************************
268 
269   Synopsis    [Deletes the node and MFFC of the node.]
270 
271   Description []
272 
273   SideEffects []
274 
275   SeeAlso     []
276 
277 ***********************************************************************/
Abc_NtkDeleteObj_rec(Abc_Obj_t * pObj,int fOnlyNodes)278 void Abc_NtkDeleteObj_rec( Abc_Obj_t * pObj, int fOnlyNodes )
279 {
280     Vec_Ptr_t * vNodes;
281     int i;
282     assert( !Abc_ObjIsComplement(pObj) );
283     assert( !Abc_ObjIsPi(pObj) );
284     assert( Abc_ObjFanoutNum(pObj) == 0 );
285     // delete fanins and fanouts
286     vNodes = Vec_PtrAlloc( 100 );
287     Abc_NodeCollectFanins( pObj, vNodes );
288     Abc_NtkDeleteObj( pObj );
289     if ( fOnlyNodes )
290     {
291         Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
292             if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) == 0 )
293                 Abc_NtkDeleteObj_rec( pObj, fOnlyNodes );
294     }
295     else
296     {
297         Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
298             if ( !Abc_ObjIsPi(pObj) && Abc_ObjFanoutNum(pObj) == 0 )
299                 Abc_NtkDeleteObj_rec( pObj, fOnlyNodes );
300     }
301     Vec_PtrFree( vNodes );
302 }
303 
304 /**Function*************************************************************
305 
306   Synopsis    [Deletes the node and MFFC of the node.]
307 
308   Description []
309 
310   SideEffects []
311 
312   SeeAlso     []
313 
314 ***********************************************************************/
Abc_NtkDeleteAll_rec(Abc_Obj_t * pObj)315 void Abc_NtkDeleteAll_rec( Abc_Obj_t * pObj )
316 {
317     Vec_Ptr_t * vNodes;
318     int i;
319     assert( !Abc_ObjIsComplement(pObj) );
320     assert( Abc_ObjFanoutNum(pObj) == 0 );
321     // delete fanins and fanouts
322     vNodes = Vec_PtrAlloc( 100 );
323     Abc_NodeCollectFanins( pObj, vNodes );
324     Abc_NtkDeleteObj( pObj );
325     Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
326         if ( !Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) == 0 )
327             Abc_NtkDeleteAll_rec( pObj );
328     Vec_PtrFree( vNodes );
329 }
330 
331 /**Function*************************************************************
332 
333   Synopsis    [Duplicate the Obj.]
334 
335   Description []
336 
337   SideEffects []
338 
339   SeeAlso     []
340 
341 ***********************************************************************/
Abc_NtkDupObj(Abc_Ntk_t * pNtkNew,Abc_Obj_t * pObj,int fCopyName)342 Abc_Obj_t * Abc_NtkDupObj( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, int fCopyName )
343 {
344     Abc_Obj_t * pObjNew;
345     // create the new object
346     pObjNew = Abc_NtkCreateObj( pNtkNew, (Abc_ObjType_t)pObj->Type );
347     // transfer names of the terminal objects
348     if ( fCopyName )
349     {
350         if ( Abc_ObjIsCi(pObj) )
351         {
352             if ( !Abc_NtkIsNetlist(pNtkNew) )
353                 Abc_ObjAssignName( pObjNew, Abc_ObjName(Abc_ObjFanout0Ntk(pObj)), NULL );
354         }
355         else if ( Abc_ObjIsCo(pObj) )
356         {
357             if ( !Abc_NtkIsNetlist(pNtkNew) )
358             {
359                 if ( Abc_ObjIsPo(pObj) )
360                     Abc_ObjAssignName( pObjNew, Abc_ObjName(Abc_ObjFanin0Ntk(pObj)), NULL );
361                 else
362                 {
363                     assert( Abc_ObjIsLatch(Abc_ObjFanout0(pObj)) );
364                     Abc_ObjAssignName( pObjNew, Abc_ObjName(pObj), NULL );
365                 }
366             }
367         }
368         else if ( Abc_ObjIsBox(pObj) || Abc_ObjIsNet(pObj) )
369             Abc_ObjAssignName( pObjNew, Abc_ObjName(pObj), NULL );
370     }
371     // copy functionality/names
372     if ( Abc_ObjIsNode(pObj) ) // copy the function if functionality is compatible
373     {
374         if ( pNtkNew->ntkFunc == pObj->pNtk->ntkFunc )
375         {
376             if ( Abc_NtkIsStrash(pNtkNew) )
377             {}
378             else if ( Abc_NtkHasSop(pNtkNew) || Abc_NtkHasBlifMv(pNtkNew) )
379                 pObjNew->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, (char *)pObj->pData );
380 #ifdef ABC_USE_CUDD
381             else if ( Abc_NtkHasBdd(pNtkNew) )
382                 pObjNew->pData = Cudd_bddTransfer((DdManager *)pObj->pNtk->pManFunc, (DdManager *)pNtkNew->pManFunc, (DdNode *)pObj->pData), Cudd_Ref((DdNode *)pObjNew->pData);
383 #endif
384             else if ( Abc_NtkHasAig(pNtkNew) )
385                 pObjNew->pData = Hop_Transfer((Hop_Man_t *)pObj->pNtk->pManFunc, (Hop_Man_t *)pNtkNew->pManFunc, (Hop_Obj_t *)pObj->pData, Abc_ObjFaninNum(pObj));
386             else if ( Abc_NtkHasMapping(pNtkNew) )
387                 pObjNew->pData = pObj->pData, pNtkNew->nBarBufs2 += !pObj->pData;
388             else assert( 0 );
389         }
390     }
391     else if ( Abc_ObjIsNet(pObj) ) // copy the name
392     {
393     }
394     else if ( Abc_ObjIsLatch(pObj) ) // copy the reset value
395         pObjNew->pData = pObj->pData;
396     // transfer HAIG
397 //    pObjNew->pEquiv = pObj->pEquiv;
398     // remember the new node in the old node
399     pObj->pCopy = pObjNew;
400     return pObjNew;
401 }
402 
403 /**Function*************************************************************
404 
405   Synopsis    [Duplicates the latch with its input/output terminals.]
406 
407   Description []
408 
409   SideEffects []
410 
411   SeeAlso     []
412 
413 ***********************************************************************/
Abc_NtkDupBox(Abc_Ntk_t * pNtkNew,Abc_Obj_t * pBox,int fCopyName)414 Abc_Obj_t * Abc_NtkDupBox( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pBox, int fCopyName )
415 {
416     Abc_Obj_t * pTerm, * pBoxNew;
417     int i;
418     assert( Abc_ObjIsBox(pBox) );
419     // duplicate the box
420     pBoxNew = Abc_NtkDupObj( pNtkNew, pBox, fCopyName );
421     // duplicate the fanins and connect them
422     Abc_ObjForEachFanin( pBox, pTerm, i )
423         Abc_ObjAddFanin( pBoxNew, Abc_NtkDupObj(pNtkNew, pTerm, fCopyName) );
424     // duplicate the fanouts and connect them
425     Abc_ObjForEachFanout( pBox, pTerm, i )
426         Abc_ObjAddFanin( Abc_NtkDupObj(pNtkNew, pTerm, fCopyName), pBoxNew );
427     return pBoxNew;
428 }
429 
430 /**Function*************************************************************
431 
432   Synopsis    [Clones the objects in the same network but does not assign its function.]
433 
434   Description []
435 
436   SideEffects []
437 
438   SeeAlso     []
439 
440 ***********************************************************************/
Abc_NtkCloneObj(Abc_Obj_t * pObj)441 Abc_Obj_t * Abc_NtkCloneObj( Abc_Obj_t * pObj )
442 {
443     Abc_Obj_t * pClone, * pFanin;
444     int i;
445     pClone = Abc_NtkCreateObj( pObj->pNtk, (Abc_ObjType_t)pObj->Type );
446     Abc_ObjForEachFanin( pObj, pFanin, i )
447         Abc_ObjAddFanin( pClone, pFanin );
448     return pClone;
449 }
450 
451 
452 /**Function*************************************************************
453 
454   Synopsis    [Returns the net with the given name.]
455 
456   Description []
457 
458   SideEffects []
459 
460   SeeAlso     []
461 
462 ***********************************************************************/
Abc_NtkFindNode(Abc_Ntk_t * pNtk,char * pName)463 Abc_Obj_t * Abc_NtkFindNode( Abc_Ntk_t * pNtk, char * pName )
464 {
465     Abc_Obj_t * pObj;
466     int Num;
467     // try to find the terminal
468     Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_PO );
469     if ( Num >= 0 )
470         return Abc_ObjFanin0( Abc_NtkObj( pNtk, Num ) );
471     Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BI );
472     if ( Num >= 0 )
473         return Abc_ObjFanin0( Abc_NtkObj( pNtk, Num ) );
474     Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_NODE );
475     if ( Num >= 0 )
476         return Abc_NtkObj( pNtk, Num );
477     // find the internal node
478     if ( pName[0] != 'n' )
479     {
480         printf( "Name \"%s\" is not found among CO or node names (internal names often look as \"n<num>\").\n", pName );
481         return NULL;
482     }
483     Num = atoi( pName + 1 );
484     if ( Num < 0 || Num >= Abc_NtkObjNumMax(pNtk) )
485     {
486         printf( "The node \"%s\" with ID %d is not in the current network.\n", pName, Num );
487         return NULL;
488     }
489     pObj = Abc_NtkObj( pNtk, Num );
490     if ( pObj == NULL )
491     {
492         printf( "The node \"%s\" with ID %d has been removed from the current network.\n", pName, Num );
493         return NULL;
494     }
495     if ( !Abc_ObjIsNode(pObj) )
496     {
497         printf( "Object with ID %d is not a node.\n", Num );
498         return NULL;
499     }
500     return pObj;
501 }
502 
503 /**Function*************************************************************
504 
505   Synopsis    [Returns the net with the given name.]
506 
507   Description []
508 
509   SideEffects []
510 
511   SeeAlso     []
512 
513 ***********************************************************************/
Abc_NtkFindNet(Abc_Ntk_t * pNtk,char * pName)514 Abc_Obj_t * Abc_NtkFindNet( Abc_Ntk_t * pNtk, char * pName )
515 {
516     Abc_Obj_t * pNet;
517     int ObjId;
518     assert( Abc_NtkIsNetlist(pNtk) );
519     ObjId = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_NET );
520     if ( ObjId == -1 )
521         return NULL;
522     pNet = Abc_NtkObj( pNtk, ObjId );
523     return pNet;
524 }
525 
526 /**Function*************************************************************
527 
528  Synopsis    [Returns CI with the given name.]
529 
530  Description []
531 
532  SideEffects []
533 
534  SeeAlso     []
535 
536 ***********************************************************************/
Abc_NtkFindCi(Abc_Ntk_t * pNtk,char * pName)537 Abc_Obj_t * Abc_NtkFindCi( Abc_Ntk_t * pNtk, char * pName )
538 {
539     int Num;
540     assert( !Abc_NtkIsNetlist(pNtk) );
541     Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_PI );
542     if ( Num >= 0 )
543         return Abc_NtkObj( pNtk, Num );
544     Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BO );
545     if ( Num >= 0 )
546         return Abc_NtkObj( pNtk, Num );
547     return NULL;
548 }
549 
550 /**Function*************************************************************
551 
552  Synopsis    [Returns CO with the given name.]
553 
554  Description []
555 
556  SideEffects []
557 
558  SeeAlso     []
559 
560 ***********************************************************************/
Abc_NtkFindCo(Abc_Ntk_t * pNtk,char * pName)561 Abc_Obj_t * Abc_NtkFindCo( Abc_Ntk_t * pNtk, char * pName )
562 {
563     int Num;
564     assert( !Abc_NtkIsNetlist(pNtk) );
565     Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_PO );
566     if ( Num >= 0 )
567         return Abc_NtkObj( pNtk, Num );
568     Num = Nm_ManFindIdByName( pNtk->pManName, pName, ABC_OBJ_BI );
569     if ( Num >= 0 )
570         return Abc_NtkObj( pNtk, Num );
571     return NULL;
572 }
573 
574 
575 /**Function*************************************************************
576 
577   Synopsis    [Finds or creates the net.]
578 
579   Description []
580 
581   SideEffects []
582 
583   SeeAlso     []
584 
585 ***********************************************************************/
Abc_NtkFindOrCreateNet(Abc_Ntk_t * pNtk,char * pName)586 Abc_Obj_t * Abc_NtkFindOrCreateNet( Abc_Ntk_t * pNtk, char * pName )
587 {
588     Abc_Obj_t * pNet;
589     assert( Abc_NtkIsNetlist(pNtk) );
590     if ( pName && (pNet = Abc_NtkFindNet( pNtk, pName )) )
591         return pNet;
592 //printf( "Creating net %s.\n", pName );
593     // create a new net
594     pNet = Abc_NtkCreateNet( pNtk );
595     if ( pName )
596         Nm_ManStoreIdName( pNtk->pManName, pNet->Id, pNet->Type, pName, NULL );
597     return pNet;
598 }
599 
600 /**Function*************************************************************
601 
602   Synopsis    [Creates constant 0 node.]
603 
604   Description []
605 
606   SideEffects []
607 
608   SeeAlso     []
609 
610 ***********************************************************************/
Abc_NtkCreateNodeConst0(Abc_Ntk_t * pNtk)611 Abc_Obj_t * Abc_NtkCreateNodeConst0( Abc_Ntk_t * pNtk )
612 {
613     Abc_Obj_t * pNode;
614     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
615     pNode = Abc_NtkCreateNode( pNtk );
616     if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) )
617         pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 0\n" );
618 #ifdef ABC_USE_CUDD
619     else if ( Abc_NtkHasBdd(pNtk) )
620         pNode->pData = Cudd_ReadLogicZero((DdManager *)pNtk->pManFunc), Cudd_Ref( (DdNode *)pNode->pData );
621 #endif
622     else if ( Abc_NtkHasAig(pNtk) )
623         pNode->pData = Hop_ManConst0((Hop_Man_t *)pNtk->pManFunc);
624     else if ( Abc_NtkHasMapping(pNtk) )
625         pNode->pData = Mio_LibraryReadConst0((Mio_Library_t *)Abc_FrameReadLibGen());
626     else if ( !Abc_NtkHasBlackbox(pNtk) )
627         assert( 0 );
628     return pNode;
629 }
630 
631 /**Function*************************************************************
632 
633   Synopsis    [Creates constant 1 node.]
634 
635   Description []
636 
637   SideEffects []
638 
639   SeeAlso     []
640 
641 ***********************************************************************/
Abc_NtkCreateNodeConst1(Abc_Ntk_t * pNtk)642 Abc_Obj_t * Abc_NtkCreateNodeConst1( Abc_Ntk_t * pNtk )
643 {
644     Abc_Obj_t * pNode;
645     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
646     pNode = Abc_NtkCreateNode( pNtk );
647     if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) )
648         pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, " 1\n" );
649 #ifdef ABC_USE_CUDD
650     else if ( Abc_NtkHasBdd(pNtk) )
651         pNode->pData = Cudd_ReadOne((DdManager *)pNtk->pManFunc), Cudd_Ref( (DdNode *)pNode->pData );
652 #endif
653     else if ( Abc_NtkHasAig(pNtk) )
654         pNode->pData = Hop_ManConst1((Hop_Man_t *)pNtk->pManFunc);
655     else if ( Abc_NtkHasMapping(pNtk) )
656         pNode->pData = Mio_LibraryReadConst1((Mio_Library_t *)Abc_FrameReadLibGen());
657     else if ( !Abc_NtkHasBlackbox(pNtk) )
658         assert( 0 );
659     return pNode;
660 }
661 
662 /**Function*************************************************************
663 
664   Synopsis    [Creates inverter.]
665 
666   Description []
667 
668   SideEffects []
669 
670   SeeAlso     []
671 
672 ***********************************************************************/
Abc_NtkCreateNodeInv(Abc_Ntk_t * pNtk,Abc_Obj_t * pFanin)673 Abc_Obj_t * Abc_NtkCreateNodeInv( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
674 {
675     Abc_Obj_t * pNode;
676     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
677     pNode = Abc_NtkCreateNode( pNtk );
678     if ( pFanin ) Abc_ObjAddFanin( pNode, pFanin );
679     if ( Abc_NtkHasSop(pNtk) )
680         pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, "0 1\n" );
681 #ifdef ABC_USE_CUDD
682     else if ( Abc_NtkHasBdd(pNtk) )
683         pNode->pData = Cudd_Not(Cudd_bddIthVar((DdManager *)pNtk->pManFunc,0)), Cudd_Ref( (DdNode *)pNode->pData );
684 #endif
685     else if ( Abc_NtkHasAig(pNtk) )
686         pNode->pData = Hop_Not(Hop_IthVar((Hop_Man_t *)pNtk->pManFunc,0));
687     else if ( Abc_NtkHasMapping(pNtk) )
688         pNode->pData = Mio_LibraryReadInv((Mio_Library_t *)Abc_FrameReadLibGen());
689     else
690         assert( 0 );
691     return pNode;
692 }
693 
694 /**Function*************************************************************
695 
696   Synopsis    [Creates buffer.]
697 
698   Description []
699 
700   SideEffects []
701 
702   SeeAlso     []
703 
704 ***********************************************************************/
Abc_NtkCreateNodeBuf(Abc_Ntk_t * pNtk,Abc_Obj_t * pFanin)705 Abc_Obj_t * Abc_NtkCreateNodeBuf( Abc_Ntk_t * pNtk, Abc_Obj_t * pFanin )
706 {
707     Abc_Obj_t * pNode;
708     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
709     pNode = Abc_NtkCreateNode( pNtk );
710     if ( pFanin ) Abc_ObjAddFanin( pNode, pFanin );
711     if ( Abc_NtkHasSop(pNtk) )
712         pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, "1 1\n" );
713 #ifdef ABC_USE_CUDD
714     else if ( Abc_NtkHasBdd(pNtk) )
715         pNode->pData = Cudd_bddIthVar((DdManager *)pNtk->pManFunc,0), Cudd_Ref( (DdNode *)pNode->pData );
716 #endif
717     else if ( Abc_NtkHasAig(pNtk) )
718         pNode->pData = Hop_IthVar((Hop_Man_t *)pNtk->pManFunc,0);
719     else if ( Abc_NtkHasMapping(pNtk) )
720         pNode->pData = Mio_LibraryReadBuf((Mio_Library_t *)Abc_FrameReadLibGen());
721     else
722         assert( 0 );
723     return pNode;
724 }
725 
726 /**Function*************************************************************
727 
728   Synopsis    [Creates AND.]
729 
730   Description []
731 
732   SideEffects []
733 
734   SeeAlso     []
735 
736 ***********************************************************************/
Abc_NtkCreateNodeAnd(Abc_Ntk_t * pNtk,Vec_Ptr_t * vFanins)737 Abc_Obj_t * Abc_NtkCreateNodeAnd( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
738 {
739     Abc_Obj_t * pNode;
740     int i;
741     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
742     pNode = Abc_NtkCreateNode( pNtk );
743     for ( i = 0; i < vFanins->nSize; i++ )
744         Abc_ObjAddFanin( pNode, (Abc_Obj_t *)vFanins->pArray[i] );
745     if ( Abc_NtkHasSop(pNtk) )
746         pNode->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtk->pManFunc, Vec_PtrSize(vFanins), NULL );
747 #ifdef ABC_USE_CUDD
748     else if ( Abc_NtkHasBdd(pNtk) )
749         pNode->pData = Extra_bddCreateAnd( (DdManager *)pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref((DdNode *)pNode->pData);
750 #endif
751     else if ( Abc_NtkHasAig(pNtk) )
752         pNode->pData = Hop_CreateAnd( (Hop_Man_t *)pNtk->pManFunc, Vec_PtrSize(vFanins) );
753     else
754         assert( 0 );
755     return pNode;
756 }
757 
758 /**Function*************************************************************
759 
760   Synopsis    [Creates OR.]
761 
762   Description []
763 
764   SideEffects []
765 
766   SeeAlso     []
767 
768 ***********************************************************************/
Abc_NtkCreateNodeOr(Abc_Ntk_t * pNtk,Vec_Ptr_t * vFanins)769 Abc_Obj_t * Abc_NtkCreateNodeOr( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
770 {
771     Abc_Obj_t * pNode;
772     int i;
773     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
774     pNode = Abc_NtkCreateNode( pNtk );
775     for ( i = 0; i < vFanins->nSize; i++ )
776         Abc_ObjAddFanin( pNode, (Abc_Obj_t *)vFanins->pArray[i] );
777     if ( Abc_NtkHasSop(pNtk) )
778         pNode->pData = Abc_SopCreateOr( (Mem_Flex_t *)pNtk->pManFunc, Vec_PtrSize(vFanins), NULL );
779 #ifdef ABC_USE_CUDD
780     else if ( Abc_NtkHasBdd(pNtk) )
781         pNode->pData = Extra_bddCreateOr( (DdManager *)pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref((DdNode *)pNode->pData);
782 #endif
783     else if ( Abc_NtkHasAig(pNtk) )
784         pNode->pData = Hop_CreateOr( (Hop_Man_t *)pNtk->pManFunc, Vec_PtrSize(vFanins) );
785     else
786         assert( 0 );
787     return pNode;
788 }
789 
790 /**Function*************************************************************
791 
792   Synopsis    [Creates EXOR.]
793 
794   Description []
795 
796   SideEffects []
797 
798   SeeAlso     []
799 
800 ***********************************************************************/
Abc_NtkCreateNodeExor(Abc_Ntk_t * pNtk,Vec_Ptr_t * vFanins)801 Abc_Obj_t * Abc_NtkCreateNodeExor( Abc_Ntk_t * pNtk, Vec_Ptr_t * vFanins )
802 {
803     Abc_Obj_t * pNode;
804     int i;
805     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
806     pNode = Abc_NtkCreateNode( pNtk );
807     for ( i = 0; i < vFanins->nSize; i++ )
808         Abc_ObjAddFanin( pNode, (Abc_Obj_t *)vFanins->pArray[i] );
809     if ( Abc_NtkHasSop(pNtk) )
810         pNode->pData = Abc_SopCreateXorSpecial( (Mem_Flex_t *)pNtk->pManFunc, Vec_PtrSize(vFanins) );
811 #ifdef ABC_USE_CUDD
812     else if ( Abc_NtkHasBdd(pNtk) )
813         pNode->pData = Extra_bddCreateExor( (DdManager *)pNtk->pManFunc, Vec_PtrSize(vFanins) ), Cudd_Ref((DdNode *)pNode->pData);
814 #endif
815     else if ( Abc_NtkHasAig(pNtk) )
816         pNode->pData = Hop_CreateExor( (Hop_Man_t *)pNtk->pManFunc, Vec_PtrSize(vFanins) );
817     else
818         assert( 0 );
819     return pNode;
820 }
821 
822 /**Function*************************************************************
823 
824   Synopsis    [Creates MUX.]
825 
826   Description []
827 
828   SideEffects []
829 
830   SeeAlso     []
831 
832 ***********************************************************************/
Abc_NtkCreateNodeMux(Abc_Ntk_t * pNtk,Abc_Obj_t * pNodeC,Abc_Obj_t * pNode1,Abc_Obj_t * pNode0)833 Abc_Obj_t * Abc_NtkCreateNodeMux( Abc_Ntk_t * pNtk, Abc_Obj_t * pNodeC, Abc_Obj_t * pNode1, Abc_Obj_t * pNode0 )
834 {
835     Abc_Obj_t * pNode;
836     assert( Abc_NtkIsLogic(pNtk) );
837     pNode = Abc_NtkCreateNode( pNtk );
838     Abc_ObjAddFanin( pNode, pNodeC );
839     Abc_ObjAddFanin( pNode, pNode1 );
840     Abc_ObjAddFanin( pNode, pNode0 );
841     if ( Abc_NtkHasSop(pNtk) )
842         pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtk->pManFunc, "11- 1\n0-1 1\n" );
843 #ifdef ABC_USE_CUDD
844     else if ( Abc_NtkHasBdd(pNtk) )
845         pNode->pData = Cudd_bddIte((DdManager *)pNtk->pManFunc,Cudd_bddIthVar((DdManager *)pNtk->pManFunc,0),Cudd_bddIthVar((DdManager *)pNtk->pManFunc,1),Cudd_bddIthVar((DdManager *)pNtk->pManFunc,2)), Cudd_Ref( (DdNode *)pNode->pData );
846 #endif
847     else if ( Abc_NtkHasAig(pNtk) )
848         pNode->pData = Hop_Mux((Hop_Man_t *)pNtk->pManFunc,Hop_IthVar((Hop_Man_t *)pNtk->pManFunc,0),Hop_IthVar((Hop_Man_t *)pNtk->pManFunc,1),Hop_IthVar((Hop_Man_t *)pNtk->pManFunc,2));
849     else
850         assert( 0 );
851     return pNode;
852 }
853 
854 
855 /**Function*************************************************************
856 
857   Synopsis    [Returns 1 if the node is a constant 0 node.]
858 
859   Description []
860 
861   SideEffects []
862 
863   SeeAlso     []
864 
865 ***********************************************************************/
Abc_NodeIsConst(Abc_Obj_t * pNode)866 int Abc_NodeIsConst( Abc_Obj_t * pNode )
867 {
868     assert( Abc_NtkIsLogic(pNode->pNtk) || Abc_NtkIsNetlist(pNode->pNtk) );
869     return Abc_ObjIsNode(pNode) && Abc_ObjFaninNum(pNode) == 0;
870 }
871 
872 /**Function*************************************************************
873 
874   Synopsis    [Returns 1 if the node is a constant 0 node.]
875 
876   Description []
877 
878   SideEffects []
879 
880   SeeAlso     []
881 
882 ***********************************************************************/
Abc_NodeIsConst0(Abc_Obj_t * pNode)883 int Abc_NodeIsConst0( Abc_Obj_t * pNode )
884 {
885     Abc_Ntk_t * pNtk = pNode->pNtk;
886     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
887     assert( Abc_ObjIsNode(pNode) );
888     if ( !Abc_NodeIsConst(pNode) )
889         return 0;
890     if ( Abc_NtkHasSop(pNtk) )
891         return Abc_SopIsConst0((char *)pNode->pData);
892 #ifdef ABC_USE_CUDD
893     if ( Abc_NtkHasBdd(pNtk) )
894         return Cudd_IsComplement(pNode->pData);
895 #endif
896     if ( Abc_NtkHasAig(pNtk) )
897         return Hop_IsComplement((Hop_Obj_t *)pNode->pData)? 1:0;
898     if ( Abc_NtkHasMapping(pNtk) )
899         return pNode->pData == Mio_LibraryReadConst0((Mio_Library_t *)Abc_FrameReadLibGen());
900     assert( 0 );
901     return 0;
902 }
903 
904 /**Function*************************************************************
905 
906   Synopsis    [Returns 1 if the node is a constant 1 node.]
907 
908   Description []
909 
910   SideEffects []
911 
912   SeeAlso     []
913 
914 ***********************************************************************/
Abc_NodeIsConst1(Abc_Obj_t * pNode)915 int Abc_NodeIsConst1( Abc_Obj_t * pNode )
916 {
917     Abc_Ntk_t * pNtk = pNode->pNtk;
918     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
919     assert( Abc_ObjIsNode(pNode) );
920     if ( !Abc_NodeIsConst(pNode) )
921         return 0;
922     if ( Abc_NtkHasSop(pNtk) )
923         return Abc_SopIsConst1((char *)pNode->pData);
924 #ifdef ABC_USE_CUDD
925     if ( Abc_NtkHasBdd(pNtk) )
926         return !Cudd_IsComplement(pNode->pData);
927 #endif
928     if ( Abc_NtkHasAig(pNtk) )
929         return !Hop_IsComplement((Hop_Obj_t *)pNode->pData);
930     if ( Abc_NtkHasMapping(pNtk) )
931         return pNode->pData == Mio_LibraryReadConst1((Mio_Library_t *)Abc_FrameReadLibGen());
932     assert( 0 );
933     return 0;
934 }
935 
936 /**Function*************************************************************
937 
938   Synopsis    [Returns 1 if the node is a buffer.]
939 
940   Description []
941 
942   SideEffects []
943 
944   SeeAlso     []
945 
946 ***********************************************************************/
Abc_NodeIsBuf(Abc_Obj_t * pNode)947 int Abc_NodeIsBuf( Abc_Obj_t * pNode )
948 {
949     Abc_Ntk_t * pNtk = pNode->pNtk;
950     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
951     assert( Abc_ObjIsNode(pNode) );
952     if ( Abc_ObjFaninNum(pNode) != 1 )
953         return 0;
954     if ( Abc_NtkHasSop(pNtk) )
955         return Abc_SopIsBuf((char *)pNode->pData);
956 #ifdef ABC_USE_CUDD
957     if ( Abc_NtkHasBdd(pNtk) )
958         return !Cudd_IsComplement(pNode->pData);
959 #endif
960     if ( Abc_NtkHasAig(pNtk) )
961         return !Hop_IsComplement((Hop_Obj_t *)pNode->pData);
962     if ( Abc_NtkHasMapping(pNtk) )
963         return pNode->pData == Mio_LibraryReadBuf((Mio_Library_t *)Abc_FrameReadLibGen());
964     assert( 0 );
965     return 0;
966 }
967 
968 /**Function*************************************************************
969 
970   Synopsis    [Returns 1 if the node is an inverter.]
971 
972   Description []
973 
974   SideEffects []
975 
976   SeeAlso     []
977 
978 ***********************************************************************/
Abc_NodeIsInv(Abc_Obj_t * pNode)979 int Abc_NodeIsInv( Abc_Obj_t * pNode )
980 {
981     Abc_Ntk_t * pNtk = pNode->pNtk;
982     assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsNetlist(pNtk) );
983     assert( Abc_ObjIsNode(pNode) );
984     if ( Abc_ObjFaninNum(pNode) != 1 )
985         return 0;
986     if ( Abc_NtkHasSop(pNtk) )
987         return Abc_SopIsInv((char *)pNode->pData);
988 #ifdef ABC_USE_CUDD
989     if ( Abc_NtkHasBdd(pNtk) )
990         return Cudd_IsComplement(pNode->pData);
991 #endif
992     if ( Abc_NtkHasAig(pNtk) )
993         return Hop_IsComplement((Hop_Obj_t *)pNode->pData)? 1:0;
994     if ( Abc_NtkHasMapping(pNtk) )
995         return pNode->pData == Mio_LibraryReadInv((Mio_Library_t *)Abc_FrameReadLibGen());
996     assert( 0 );
997     return 0;
998 }
999 
1000 /**Function*************************************************************
1001 
1002   Synopsis    [Complements the local functions of the node.]
1003 
1004   Description []
1005 
1006   SideEffects []
1007 
1008   SeeAlso     []
1009 
1010 ***********************************************************************/
Abc_NodeComplement(Abc_Obj_t * pNode)1011 void Abc_NodeComplement( Abc_Obj_t * pNode )
1012 {
1013     assert( Abc_NtkIsLogic(pNode->pNtk) || Abc_NtkIsNetlist(pNode->pNtk) );
1014     assert( Abc_ObjIsNode(pNode) );
1015     if ( Abc_NtkHasSop(pNode->pNtk) )
1016         Abc_SopComplement( (char *)pNode->pData );
1017     else if ( Abc_NtkHasAig(pNode->pNtk) )
1018         pNode->pData = Hop_Not( (Hop_Obj_t *)pNode->pData );
1019 #ifdef ABC_USE_CUDD
1020     else if ( Abc_NtkHasBdd(pNode->pNtk) )
1021         pNode->pData = Cudd_Not( pNode->pData );
1022 #endif
1023     else
1024         assert( 0 );
1025 }
1026 
1027 /**Function*************************************************************
1028 
1029   Synopsis    [Changes the polarity of one fanin.]
1030 
1031   Description []
1032 
1033   SideEffects []
1034 
1035   SeeAlso     []
1036 
1037 ***********************************************************************/
Abc_NodeComplementInput(Abc_Obj_t * pNode,Abc_Obj_t * pFanin)1038 void Abc_NodeComplementInput( Abc_Obj_t * pNode, Abc_Obj_t * pFanin )
1039 {
1040     int iFanin;
1041     if ( (iFanin = Vec_IntFind( &pNode->vFanins, pFanin->Id )) == -1 )
1042     {
1043         printf( "Node %s should be among", Abc_ObjName(pFanin) );
1044         printf( " the fanins of node %s...\n", Abc_ObjName(pNode) );
1045         return;
1046     }
1047     if ( Abc_NtkHasSop(pNode->pNtk) )
1048         Abc_SopComplementVar( (char *)pNode->pData, iFanin );
1049     else if ( Abc_NtkHasAig(pNode->pNtk) )
1050         pNode->pData = Hop_Complement( (Hop_Man_t *)pNode->pNtk->pManFunc, (Hop_Obj_t *)pNode->pData, iFanin );
1051 #ifdef ABC_USE_CUDD
1052     else if ( Abc_NtkHasBdd(pNode->pNtk) )
1053     {
1054         DdManager * dd = (DdManager *)pNode->pNtk->pManFunc;
1055         DdNode * bVar, * bCof0, * bCof1;
1056         bVar = Cudd_bddIthVar( dd, iFanin );
1057         bCof0 = Cudd_Cofactor( dd, (DdNode *)pNode->pData, Cudd_Not(bVar) );   Cudd_Ref( bCof0 );
1058         bCof1 = Cudd_Cofactor( dd, (DdNode *)pNode->pData, bVar );             Cudd_Ref( bCof1 );
1059         Cudd_RecursiveDeref( dd, (DdNode *)pNode->pData );
1060         pNode->pData = Cudd_bddIte( dd, bVar, bCof0, bCof1 );        Cudd_Ref( (DdNode *)pNode->pData );
1061         Cudd_RecursiveDeref( dd, bCof0 );
1062         Cudd_RecursiveDeref( dd, bCof1 );
1063     }
1064 #endif
1065     else
1066         assert( 0 );
1067 }
1068 
1069 
1070 ////////////////////////////////////////////////////////////////////////
1071 ///                       END OF FILE                                ///
1072 ////////////////////////////////////////////////////////////////////////
1073 
1074 ABC_NAMESPACE_IMPL_END
1075 
1076