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