1 /**CFile****************************************************************
2 
3   FileName    [abcFanio.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Network and node package.]
8 
9   Synopsis    [Various procedures to connect fanins/fanouts.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: abcFanio.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "abc.h"
22 
23 ABC_NAMESPACE_IMPL_START
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 ///                        DECLARATIONS                              ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 ////////////////////////////////////////////////////////////////////////
31 ///                     FUNCTION DEFINITIONS                         ///
32 ////////////////////////////////////////////////////////////////////////
33 
34 /**Function*************************************************************
35 
36   Synopsis    []
37 
38   Description []
39 
40   SideEffects []
41 
42   SeeAlso     []
43 
44 ***********************************************************************/
Vec_IntPushMem(Mem_Step_t * pMemMan,Vec_Int_t * p,int Entry)45 static inline void Vec_IntPushMem( Mem_Step_t * pMemMan, Vec_Int_t * p, int Entry )
46 {
47     if ( p->nSize == p->nCap )
48     {
49         int * pArray;
50         int i;
51 
52         if ( p->nSize == 0 )
53             p->nCap = 1;
54         if ( pMemMan )
55             pArray = (int *)Mem_StepEntryFetch( pMemMan, p->nCap * 8 );
56         else
57             pArray = ABC_ALLOC( int, p->nCap * 2 );
58         if ( p->pArray )
59         {
60             for ( i = 0; i < p->nSize; i++ )
61                 pArray[i] = p->pArray[i];
62             if ( pMemMan )
63                 Mem_StepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 );
64             else
65                 ABC_FREE( p->pArray );
66         }
67         p->nCap *= 2;
68         p->pArray = pArray;
69     }
70     p->pArray[p->nSize++] = Entry;
71 }
72 
73 /**Function*************************************************************
74 
75   Synopsis    [Creates fanout/fanin relationship between the nodes.]
76 
77   Description []
78 
79   SideEffects []
80 
81   SeeAlso     []
82 
83 ***********************************************************************/
Abc_ObjAddFanin(Abc_Obj_t * pObj,Abc_Obj_t * pFanin)84 void Abc_ObjAddFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
85 {
86     Abc_Obj_t * pFaninR = Abc_ObjRegular(pFanin);
87     assert( !Abc_ObjIsComplement(pObj) );
88     assert( pObj->pNtk == pFaninR->pNtk );
89     assert( pObj->Id >= 0 && pFaninR->Id >= 0 );
90     assert( !Abc_ObjIsPi(pObj) && !Abc_ObjIsPo(pFaninR) );    // fanin of PI or fanout of PO
91     assert( !Abc_ObjIsCo(pObj) || !Abc_ObjFaninNum(pObj) );  // CO with two fanins
92     assert( !Abc_ObjIsNet(pObj) || !Abc_ObjFaninNum(pObj) ); // net with two fanins
93     Vec_IntPushMem( pObj->pNtk->pMmStep, &pObj->vFanins,     pFaninR->Id );
94     Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninR->vFanouts, pObj->Id    );
95     if ( Abc_ObjIsComplement(pFanin) )
96         Abc_ObjSetFaninC( pObj, Abc_ObjFaninNum(pObj)-1 );
97 }
98 
99 
100 /**Function*************************************************************
101 
102   Synopsis    [Destroys fanout/fanin relationship between the nodes.]
103 
104   Description []
105 
106   SideEffects []
107 
108   SeeAlso     []
109 
110 ***********************************************************************/
Abc_ObjDeleteFanin(Abc_Obj_t * pObj,Abc_Obj_t * pFanin)111 void Abc_ObjDeleteFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFanin )
112 {
113     assert( !Abc_ObjIsComplement(pObj) );
114     assert( !Abc_ObjIsComplement(pFanin) );
115     assert( pObj->pNtk == pFanin->pNtk );
116     assert( pObj->Id >= 0 && pFanin->Id >= 0 );
117     if ( !Vec_IntRemove( &pObj->vFanins, pFanin->Id ) )
118     {
119         printf( "The obj %d is not found among the fanins of obj %d ...\n", pFanin->Id, pObj->Id );
120         return;
121     }
122     if ( !Vec_IntRemove( &pFanin->vFanouts, pObj->Id ) )
123     {
124         printf( "The obj %d is not found among the fanouts of obj %d ...\n", pObj->Id, pFanin->Id );
125         return;
126     }
127 }
128 
129 
130 /**Function*************************************************************
131 
132   Synopsis    [Destroys fanout/fanin relationship between the nodes.]
133 
134   Description []
135 
136   SideEffects []
137 
138   SeeAlso     []
139 
140 ***********************************************************************/
Abc_ObjRemoveFanins(Abc_Obj_t * pObj)141 void Abc_ObjRemoveFanins( Abc_Obj_t * pObj )
142 {
143     Vec_Int_t * vFaninsOld;
144     Abc_Obj_t * pFanin;
145     int k;
146     // remove old fanins
147     vFaninsOld = &pObj->vFanins;
148     for ( k = vFaninsOld->nSize - 1; k >= 0; k-- )
149     {
150         pFanin = Abc_NtkObj( pObj->pNtk, vFaninsOld->pArray[k] );
151         Abc_ObjDeleteFanin( pObj, pFanin );
152     }
153     pObj->fCompl0 = 0;
154     pObj->fCompl1 = 0;
155     assert( vFaninsOld->nSize == 0 );
156 }
157 
158 /**Function*************************************************************
159 
160   Synopsis    [Replaces a fanin of the node.]
161 
162   Description [The node is pObj. An old fanin of this node (pFaninOld) has to be
163   replaced by a new fanin (pFaninNew). Assumes that the node and the old fanin
164   are not complemented. The new fanin can be complemented. In this case, the
165   polarity of the new fanin will change, compared to the polarity of the old fanin.]
166 
167   SideEffects []
168 
169   SeeAlso     []
170 
171 ***********************************************************************/
Abc_ObjPatchFanin(Abc_Obj_t * pObj,Abc_Obj_t * pFaninOld,Abc_Obj_t * pFaninNew)172 void Abc_ObjPatchFanin( Abc_Obj_t * pObj, Abc_Obj_t * pFaninOld, Abc_Obj_t * pFaninNew )
173 {
174     Abc_Obj_t * pFaninNewR = Abc_ObjRegular(pFaninNew);
175     int iFanin;//, nLats;//, fCompl;
176     assert( !Abc_ObjIsComplement(pObj) );
177     assert( !Abc_ObjIsComplement(pFaninOld) );
178     assert( pFaninOld != pFaninNewR );
179 //    assert( pObj != pFaninOld );
180 //    assert( pObj != pFaninNewR );
181     assert( pObj->pNtk == pFaninOld->pNtk );
182     assert( pObj->pNtk == pFaninNewR->pNtk );
183     if ( (iFanin = Vec_IntFind( &pObj->vFanins, pFaninOld->Id )) == -1 )
184     {
185         printf( "Node %s is not among", Abc_ObjName(pFaninOld) );
186         printf( " the fanins of node %s...\n", Abc_ObjName(pObj) );
187         return;
188     }
189 
190     // remember the attributes of the old fanin
191 //    fCompl = Abc_ObjFaninC(pObj, iFanin);
192     // replace the old fanin entry by the new fanin entry (removes attributes)
193     Vec_IntWriteEntry( &pObj->vFanins, iFanin, pFaninNewR->Id );
194     // set the attributes of the new fanin
195 //    if ( fCompl ^ Abc_ObjIsComplement(pFaninNew) )
196 //        Abc_ObjSetFaninC( pObj, iFanin );
197     if ( Abc_ObjIsComplement(pFaninNew) )
198         Abc_ObjXorFaninC( pObj, iFanin );
199 
200 //    if ( Abc_NtkIsSeq(pObj->pNtk) && (nLats = Seq_ObjFaninL(pObj, iFanin)) )
201 //        Seq_ObjSetFaninL( pObj, iFanin, nLats );
202     // update the fanout of the fanin
203     if ( !Vec_IntRemove( &pFaninOld->vFanouts, pObj->Id ) )
204     {
205         printf( "Node %s is not among", Abc_ObjName(pObj) );
206         printf( " the fanouts of its old fanin %s...\n", Abc_ObjName(pFaninOld) );
207 //        return;
208     }
209     Vec_IntPushMem( pObj->pNtk->pMmStep, &pFaninNewR->vFanouts, pObj->Id );
210 }
211 
212 /**Function*************************************************************
213 
214   Synopsis    [Replaces pObj by iObjNew in the fanin arrays of the fanouts.]
215 
216   Description []
217 
218   SideEffects []
219 
220   SeeAlso     []
221 
222 ***********************************************************************/
Abc_ObjPatchFanoutFanin(Abc_Obj_t * pObj,int iObjNew)223 void Abc_ObjPatchFanoutFanin( Abc_Obj_t * pObj, int iObjNew )
224 {
225     Abc_Obj_t * pFanout;
226     int i, k, Entry;
227     // update fanouts of the node to point to this one
228     Abc_ObjForEachFanout( pObj, pFanout, i )
229     {
230         Vec_IntForEachEntry( &pFanout->vFanins, Entry, k )
231             if ( Entry == (int)Abc_ObjId(pObj) )
232             {
233                 Vec_IntWriteEntry( &pFanout->vFanins, k, iObjNew );
234                 break;
235             }
236         assert( k < Vec_IntSize(&pFanout->vFanins) );
237     }
238 }
239 
240 /**Function*************************************************************
241 
242   Synopsis    [Inserts one-input node of the type specified between the nodes.]
243 
244   Description []
245 
246   SideEffects []
247 
248   SeeAlso     []
249 
250 ***********************************************************************/
Abc_ObjInsertBetween(Abc_Obj_t * pNodeIn,Abc_Obj_t * pNodeOut,Abc_ObjType_t Type)251 Abc_Obj_t * Abc_ObjInsertBetween( Abc_Obj_t * pNodeIn, Abc_Obj_t * pNodeOut, Abc_ObjType_t Type )
252 {
253     Abc_Obj_t * pNodeNew;
254     int iFanoutIndex, iFaninIndex;
255     // find pNodeOut among the fanouts of pNodeIn
256     if ( (iFanoutIndex = Vec_IntFind( &pNodeIn->vFanouts, pNodeOut->Id )) == -1 )
257     {
258         printf( "Node %s is not among", Abc_ObjName(pNodeOut) );
259         printf( " the fanouts of node %s...\n", Abc_ObjName(pNodeIn) );
260         return NULL;
261     }
262     // find pNodeIn among the fanins of pNodeOut
263     if ( (iFaninIndex = Vec_IntFind( &pNodeOut->vFanins, pNodeIn->Id )) == -1 )
264     {
265         printf( "Node %s is not among", Abc_ObjName(pNodeIn) );
266         printf( " the fanins of node %s...\n", Abc_ObjName(pNodeOut) );
267         return NULL;
268     }
269     // create the new node
270     pNodeNew = Abc_NtkCreateObj( pNodeIn->pNtk, Type );
271     // add pNodeIn as fanin and pNodeOut as fanout
272     Vec_IntPushMem( pNodeNew->pNtk->pMmStep, &pNodeNew->vFanins,  pNodeIn->Id  );
273     Vec_IntPushMem( pNodeNew->pNtk->pMmStep, &pNodeNew->vFanouts, pNodeOut->Id );
274     // update the fanout of pNodeIn
275     Vec_IntWriteEntry( &pNodeIn->vFanouts, iFanoutIndex, pNodeNew->Id );
276     // update the fanin of pNodeOut
277     Vec_IntWriteEntry( &pNodeOut->vFanins, iFaninIndex, pNodeNew->Id );
278     return pNodeNew;
279 }
280 
281 /**Function*************************************************************
282 
283   Synopsis    [Transfers fanout from the old node to the new node.]
284 
285   Description []
286 
287   SideEffects []
288 
289   SeeAlso     []
290 
291 ***********************************************************************/
Abc_ObjTransferFanout(Abc_Obj_t * pNodeFrom,Abc_Obj_t * pNodeTo)292 void Abc_ObjTransferFanout( Abc_Obj_t * pNodeFrom, Abc_Obj_t * pNodeTo )
293 {
294     Vec_Ptr_t * vFanouts;
295     int nFanoutsOld, i;
296     assert( !Abc_ObjIsComplement(pNodeFrom) );
297     assert( !Abc_ObjIsComplement(pNodeTo) );
298     assert( !Abc_ObjIsPo(pNodeFrom) && !Abc_ObjIsPo(pNodeTo) );
299     assert( pNodeFrom->pNtk == pNodeTo->pNtk );
300     assert( pNodeFrom != pNodeTo );
301     assert( !Abc_ObjIsNode(pNodeFrom) || Abc_ObjFanoutNum(pNodeFrom) > 0 );
302     // get the fanouts of the old node
303     nFanoutsOld = Abc_ObjFanoutNum(pNodeTo);
304     vFanouts = Vec_PtrAlloc( nFanoutsOld );
305     Abc_NodeCollectFanouts( pNodeFrom, vFanouts );
306     // patch the fanin of each of them
307     for ( i = 0; i < vFanouts->nSize; i++ )
308         Abc_ObjPatchFanin( (Abc_Obj_t *)vFanouts->pArray[i], pNodeFrom, pNodeTo );
309     assert( Abc_ObjFanoutNum(pNodeFrom) == 0 );
310     assert( Abc_ObjFanoutNum(pNodeTo) == nFanoutsOld + vFanouts->nSize );
311     Vec_PtrFree( vFanouts );
312 }
313 
314 /**Function*************************************************************
315 
316   Synopsis    [Replaces the node by a new node.]
317 
318   Description []
319 
320   SideEffects []
321 
322   SeeAlso     []
323 
324 ***********************************************************************/
Abc_ObjReplace(Abc_Obj_t * pNodeOld,Abc_Obj_t * pNodeNew)325 void Abc_ObjReplace( Abc_Obj_t * pNodeOld, Abc_Obj_t * pNodeNew )
326 {
327     assert( !Abc_ObjIsComplement(pNodeOld) );
328     assert( !Abc_ObjIsComplement(pNodeNew) );
329     assert( pNodeOld->pNtk == pNodeNew->pNtk );
330     assert( pNodeOld != pNodeNew );
331     assert( Abc_ObjFanoutNum(pNodeOld) > 0 );
332     // transfer the fanouts to the old node
333     Abc_ObjTransferFanout( pNodeOld, pNodeNew );
334     // remove the old node
335     Abc_NtkDeleteObj_rec( pNodeOld, 1 );
336 }
337 
338 /**Function*************************************************************
339 
340   Synopsis    [Replaces a node by a constant.]
341 
342   Description []
343 
344   SideEffects []
345 
346   SeeAlso     []
347 
348 ***********************************************************************/
Abc_ObjReplaceByConstant(Abc_Obj_t * pNode,int fConst1)349 void Abc_ObjReplaceByConstant( Abc_Obj_t * pNode, int fConst1 )
350 {
351     Abc_Obj_t * pNodeNew;
352     assert( Abc_NtkIsLogic(pNode->pNtk) );
353     assert( !Abc_ObjIsCo(pNode) );
354     pNodeNew = fConst1 ? Abc_NtkCreateNodeConst1(pNode->pNtk) : Abc_NtkCreateNodeConst0(pNode->pNtk);
355     // transfer the fanouts to the old node
356     Abc_ObjTransferFanout( pNode, pNodeNew );
357     // remove the old node
358     if ( Abc_ObjIsNode(pNode) )
359         Abc_NtkDeleteObj_rec( pNode, 1 );
360 }
361 
362 /**Function*************************************************************
363 
364   Synopsis    [Returns the index of the fanin in the fanin list of the fanout.]
365 
366   Description []
367 
368   SideEffects []
369 
370   SeeAlso     []
371 
372 ***********************************************************************/
Abc_ObjFanoutFaninNum(Abc_Obj_t * pFanout,Abc_Obj_t * pFanin)373 int Abc_ObjFanoutFaninNum( Abc_Obj_t * pFanout, Abc_Obj_t * pFanin )
374 {
375     Abc_Obj_t * pObj;
376     int i;
377     Abc_ObjForEachFanin( pFanout, pObj, i )
378         if ( pObj == pFanin )
379             return i;
380     return -1;
381 }
382 
383 
384 ////////////////////////////////////////////////////////////////////////
385 ///                       END OF FILE                                ///
386 ////////////////////////////////////////////////////////////////////////
387 
388 
389 ABC_NAMESPACE_IMPL_END
390 
391