1 /**CFile****************************************************************
2
3 FileName [abcNetlist.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [Network and node package.]
8
9 Synopsis [Transforms netlist into a logic network and vice versa.]
10
11 Author [Alan Mishchenko]
12
13 Affiliation [UC Berkeley]
14
15 Date [Ver. 1.0. Started - June 20, 2005.]
16
17 Revision [$Id: abcNetlist.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18
19 ***********************************************************************/
20
21 #include "abc.h"
22 #include "base/main/main.h"
23 //#include "seq.h"
24
25 ABC_NAMESPACE_IMPL_START
26
27
28 ////////////////////////////////////////////////////////////////////////
29 /// DECLARATIONS ///
30 ////////////////////////////////////////////////////////////////////////
31
32 static void Abc_NtkAddPoBuffers( Abc_Ntk_t * pNtk );
33 static Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk );
34 static Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk );
35 static Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk );
36
37 ////////////////////////////////////////////////////////////////////////
38 /// FUNCTION DEFINITIONS ///
39 ////////////////////////////////////////////////////////////////////////
40
41 /**Function*************************************************************
42
43 Synopsis [Transform the netlist into a logic network.]
44
45 Description []
46
47 SideEffects []
48
49 SeeAlso []
50
51 ***********************************************************************/
Abc_NtkToLogic(Abc_Ntk_t * pNtk)52 Abc_Ntk_t * Abc_NtkToLogic( Abc_Ntk_t * pNtk )
53 {
54 Abc_Ntk_t * pNtkNew;
55 Abc_Obj_t * pObj, * pFanin;
56 int i, k;
57 // consider the case of the AIG
58 if ( Abc_NtkIsStrash(pNtk) )
59 return Abc_NtkAigToLogicSop( pNtk );
60 assert( Abc_NtkIsNetlist(pNtk) );
61 // consider simple case when there is hierarchy
62 // assert( pNtk->pDesign == NULL );
63 assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
64 assert( Abc_NtkBlackboxNum(pNtk) == 0 );
65 // start the network
66 pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, pNtk->ntkFunc );
67 // duplicate the nodes
68 Abc_NtkForEachNode( pNtk, pObj, i )
69 {
70 Abc_NtkDupObj(pNtkNew, pObj, 0);
71 Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(Abc_ObjFanout0(pObj)), NULL );
72 }
73 // reconnect the internal nodes in the new network
74 Abc_NtkForEachNode( pNtk, pObj, i )
75 Abc_ObjForEachFanin( pObj, pFanin, k )
76 Abc_ObjAddFanin( pObj->pCopy, Abc_ObjFanin0(pFanin)->pCopy );
77 // collect the CO nodes
78 Abc_NtkFinalize( pNtk, pNtkNew );
79 // fix the problem with CO pointing directly to CIs
80 Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
81 // duplicate EXDC
82 if ( pNtk->pExdc )
83 pNtkNew->pExdc = Abc_NtkToLogic( pNtk->pExdc );
84 if ( !Abc_NtkCheck( pNtkNew ) )
85 fprintf( stdout, "Abc_NtkToLogic(): Network check has failed.\n" );
86 return pNtkNew;
87 }
88
89 /**Function*************************************************************
90
91 Synopsis [Transform the logic network into a netlist.]
92
93 Description []
94
95 SideEffects []
96
97 SeeAlso []
98
99 ***********************************************************************/
Abc_NtkToNetlist(Abc_Ntk_t * pNtk)100 Abc_Ntk_t * Abc_NtkToNetlist( Abc_Ntk_t * pNtk )
101 {
102 Abc_Ntk_t * pNtkNew, * pNtkTemp;
103 assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) );
104 if ( Abc_NtkIsStrash(pNtk) )
105 {
106 pNtkTemp = Abc_NtkAigToLogicSop(pNtk);
107 pNtkNew = Abc_NtkLogicToNetlist( pNtkTemp );
108 Abc_NtkDelete( pNtkTemp );
109 return pNtkNew;
110 }
111 return Abc_NtkLogicToNetlist( pNtk );
112 }
113
114 /**Function*************************************************************
115
116 Synopsis [Converts the AIG into the netlist.]
117
118 Description [This procedure does not copy the choices.]
119
120 SideEffects []
121
122 SeeAlso []
123
124 ***********************************************************************/
Abc_NtkToNetlistBench(Abc_Ntk_t * pNtk)125 Abc_Ntk_t * Abc_NtkToNetlistBench( Abc_Ntk_t * pNtk )
126 {
127 Abc_Ntk_t * pNtkNew, * pNtkTemp;
128 assert( Abc_NtkIsStrash(pNtk) );
129 pNtkTemp = Abc_NtkAigToLogicSopBench( pNtk );
130 pNtkNew = Abc_NtkLogicToNetlist( pNtkTemp );
131 Abc_NtkDelete( pNtkTemp );
132 return pNtkNew;
133 }
134
135 /**Function*************************************************************
136
137 Synopsis [Transform the logic network into a netlist.]
138
139 Description [The logic network given to this procedure should
140 have exactly the same structure as the resulting netlist. The COs
141 can only point to CIs if they have identical names. Otherwise,
142 they should have a node between them, even if this node is
143 inverter or buffer.]
144
145 SideEffects []
146
147 SeeAlso []
148
149 ***********************************************************************/
Abc_NtkLogicToNetlist(Abc_Ntk_t * pNtk)150 Abc_Ntk_t * Abc_NtkLogicToNetlist( Abc_Ntk_t * pNtk )
151 {
152 Abc_Ntk_t * pNtkNew;
153 Abc_Obj_t * pObj, * pNet, * pDriver, * pFanin;
154 int i, k;
155
156 assert( Abc_NtkIsLogic(pNtk) );
157
158 // remove dangling nodes
159 Abc_NtkCleanup( pNtk, 0 );
160
161 // make sure the CO names are unique
162 Abc_NtkCheckUniqueCiNames( pNtk );
163 Abc_NtkCheckUniqueCoNames( pNtk );
164 Abc_NtkCheckUniqueCioNames( pNtk );
165
166 // assert( Abc_NtkLogicHasSimpleCos(pNtk) );
167 if ( !Abc_NtkLogicHasSimpleCos(pNtk) )
168 {
169 if ( !Abc_FrameReadFlag("silentmode") )
170 printf( "Abc_NtkLogicToNetlist() warning: The network is converted to have simple COs.\n" );
171 Abc_NtkLogicMakeSimpleCos( pNtk, 0 );
172 }
173
174 // start the netlist by creating PI/PO/Latch objects
175 pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_NETLIST, pNtk->ntkFunc );
176 // create the CI nets and remember them in the new CI nodes
177 Abc_NtkForEachCi( pNtk, pObj, i )
178 {
179 pNet = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pObj) );
180 Abc_ObjAddFanin( pNet, pObj->pCopy );
181 pObj->pCopy->pCopy = pNet;
182 }
183 // duplicate all nodes
184 Abc_NtkForEachNode( pNtk, pObj, i )
185 Abc_NtkDupObj(pNtkNew, pObj, 0);
186 // first add the nets to the CO drivers
187 Abc_NtkForEachCo( pNtk, pObj, i )
188 {
189 pDriver = Abc_ObjFanin0(pObj);
190 if ( Abc_ObjIsCi(pDriver) )
191 {
192 assert( !strcmp( Abc_ObjName(pDriver), Abc_ObjName(pObj) ) );
193 Abc_ObjAddFanin( pObj->pCopy, pDriver->pCopy->pCopy );
194 continue;
195 }
196 assert( Abc_ObjIsNode(pDriver) );
197 // if the CO driver has no net, create it
198 if ( pDriver->pCopy->pCopy == NULL )
199 {
200 // create the CO net and connect it to CO
201 //if ( Abc_NtkFindNet(pNtkNew, Abc_ObjName(pDriver)) == NULL )
202 // pNet = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pDriver) );
203 //else
204 pNet = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pObj) );
205 Abc_ObjAddFanin( pObj->pCopy, pNet );
206 // connect the CO net to the new driver and remember it in the new driver
207 Abc_ObjAddFanin( pNet, pDriver->pCopy );
208 pDriver->pCopy->pCopy = pNet;
209 }
210 else
211 {
212 assert( !strcmp( Abc_ObjName(pDriver->pCopy->pCopy), Abc_ObjName(pObj) ) );
213 Abc_ObjAddFanin( pObj->pCopy, pDriver->pCopy->pCopy );
214 }
215 }
216 // create the missing nets
217 Abc_NtkForEachNode( pNtk, pObj, i )
218 {
219 char Buffer[1000];
220 if ( pObj->pCopy->pCopy ) // the net of the new object is already created
221 continue;
222 // create the new net
223 sprintf( Buffer, "new_%s_", Abc_ObjName(pObj) );
224 //pNet = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pObj) ); // here we create net names such as "n48", where 48 is the ID of the node
225 pNet = Abc_NtkFindOrCreateNet( pNtkNew, Buffer );
226 Abc_ObjAddFanin( pNet, pObj->pCopy );
227 pObj->pCopy->pCopy = pNet;
228 }
229 // connect nodes to the fanins nets
230 Abc_NtkForEachNode( pNtk, pObj, i )
231 Abc_ObjForEachFanin( pObj, pFanin, k )
232 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy->pCopy );
233 // duplicate EXDC
234 if ( pNtk->pExdc )
235 pNtkNew->pExdc = Abc_NtkToNetlist( pNtk->pExdc );
236 if ( !Abc_NtkCheck( pNtkNew ) )
237 fprintf( stdout, "Abc_NtkLogicToNetlist(): Network check has failed.\n" );
238 return pNtkNew;
239 }
240
241 /**Function*************************************************************
242
243 Synopsis [Converts the AIG into the logic network with SOPs.]
244
245 Description [Correctly handles the case of choice nodes.]
246
247 SideEffects []
248
249 SeeAlso []
250
251 ***********************************************************************/
Abc_NtkAigToLogicSop(Abc_Ntk_t * pNtk)252 Abc_Ntk_t * Abc_NtkAigToLogicSop( Abc_Ntk_t * pNtk )
253 {
254 extern int Abc_NtkLogicMakeSimpleCos2( Abc_Ntk_t * pNtk, int fDuplicate );
255
256 Abc_Ntk_t * pNtkNew;
257 Abc_Obj_t * pObj, * pFanin, * pNodeNew;
258 Vec_Int_t * vInts;
259 int i, k, fChoices = 0;
260 assert( Abc_NtkIsStrash(pNtk) );
261 // start the network
262 pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
263 // if the constant node is used, duplicate it
264 pObj = Abc_AigConst1(pNtk);
265 if ( Abc_ObjFanoutNum(pObj) > 0 )
266 pObj->pCopy = Abc_NtkCreateNodeConst1(pNtkNew);
267 // duplicate the nodes and create node functions
268 Abc_NtkForEachNode( pNtk, pObj, i )
269 {
270 Abc_NtkDupObj(pNtkNew, pObj, 0);
271 pObj->pCopy->pData = Abc_SopCreateAnd2( (Mem_Flex_t *)pNtkNew->pManFunc, Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
272 }
273 // create the choice nodes
274 Abc_NtkForEachNode( pNtk, pObj, i )
275 {
276 if ( !Abc_AigNodeIsChoice(pObj) )
277 continue;
278 // create an OR gate
279 pNodeNew = Abc_NtkCreateNode(pNtkNew);
280 // add fanins
281 vInts = Vec_IntAlloc( 10 );
282 for ( pFanin = pObj; pFanin; pFanin = (Abc_Obj_t *)pFanin->pData )
283 {
284 Vec_IntPush( vInts, (int)(pObj->fPhase != pFanin->fPhase) );
285 Abc_ObjAddFanin( pNodeNew, pFanin->pCopy );
286 }
287 // create the logic function
288 pNodeNew->pData = Abc_SopCreateOrMultiCube( (Mem_Flex_t *)pNtkNew->pManFunc, Vec_IntSize(vInts), Vec_IntArray(vInts) );
289 // set the new node
290 pObj->pCopy->pCopy = pNodeNew;
291 Vec_IntFree( vInts );
292 fChoices = 1;
293 }
294 // connect the internal nodes
295 Abc_NtkForEachNode( pNtk, pObj, i )
296 Abc_ObjForEachFanin( pObj, pFanin, k )
297 if ( pFanin->pCopy->pCopy )
298 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy->pCopy );
299 else
300 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
301 // connect the COs
302 // Abc_NtkFinalize( pNtk, pNtkNew );
303 Abc_NtkForEachCo( pNtk, pObj, i )
304 {
305 pFanin = Abc_ObjFanin0(pObj);
306 if ( pFanin->pCopy->pCopy )
307 pNodeNew = Abc_ObjNotCond(pFanin->pCopy->pCopy, Abc_ObjFaninC0(pObj));
308 else
309 pNodeNew = Abc_ObjNotCond(pFanin->pCopy, Abc_ObjFaninC0(pObj));
310 Abc_ObjAddFanin( pObj->pCopy, pNodeNew );
311 }
312
313 // fix the problem with complemented and duplicated CO edges
314 if ( fChoices )
315 Abc_NtkLogicMakeSimpleCos2( pNtkNew, 0 );
316 else
317 Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
318 // duplicate the EXDC Ntk
319 if ( pNtk->pExdc )
320 {
321 if ( Abc_NtkIsStrash(pNtk->pExdc) )
322 pNtkNew->pExdc = Abc_NtkAigToLogicSop( pNtk->pExdc );
323 else
324 pNtkNew->pExdc = Abc_NtkDup( pNtk->pExdc );
325 }
326 if ( !Abc_NtkCheck( pNtkNew ) )
327 fprintf( stdout, "Abc_NtkAigToLogicSop(): Network check has failed.\n" );
328 return pNtkNew;
329 }
330
331 /**Function*************************************************************
332
333 Synopsis [Converts the AIG into the logic network with SOPs for bench writing.]
334
335 Description [This procedure does not copy the choices.]
336
337 SideEffects []
338
339 SeeAlso []
340
341 ***********************************************************************/
Abc_NtkAigToLogicSopBench(Abc_Ntk_t * pNtk)342 Abc_Ntk_t * Abc_NtkAigToLogicSopBench( Abc_Ntk_t * pNtk )
343 {
344 Abc_Ntk_t * pNtkNew;
345 Abc_Obj_t * pObj, * pFanin;
346 Vec_Ptr_t * vNodes;
347 int i, k;
348 assert( Abc_NtkIsStrash(pNtk) );
349 if ( Abc_NtkGetChoiceNum(pNtk) )
350 printf( "Warning: Choice nodes are skipped.\n" );
351 // start the network
352 pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
353 // collect the nodes to be used (marks all nodes with current TravId)
354 vNodes = Abc_NtkDfs( pNtk, 0 );
355 // create inverters for the constant node
356 pObj = Abc_AigConst1(pNtk);
357 if ( Abc_ObjFanoutNum(pObj) > 0 )
358 pObj->pCopy = Abc_NtkCreateNodeConst1(pNtkNew);
359 if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
360 pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
361 // create inverters for the CIs
362 Abc_NtkForEachCi( pNtk, pObj, i )
363 if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
364 pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
365 // duplicate the nodes, create node functions, and inverters
366 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
367 {
368 Abc_NtkDupObj( pNtkNew, pObj, 0 );
369 pObj->pCopy->pData = Abc_SopCreateAnd( (Mem_Flex_t *)pNtkNew->pManFunc, 2, NULL );
370 if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
371 pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
372 }
373 // connect the objects
374 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
375 Abc_ObjForEachFanin( pObj, pFanin, k )
376 {
377 if ( Abc_ObjFaninC( pObj, k ) )
378 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy->pCopy );
379 else
380 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
381 }
382 Vec_PtrFree( vNodes );
383 // connect the COs
384 Abc_NtkForEachCo( pNtk, pObj, i )
385 {
386 pFanin = Abc_ObjFanin0(pObj);
387 if ( Abc_ObjFaninC0( pObj ) )
388 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy->pCopy );
389 else
390 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
391 }
392 // fix the problem with complemented and duplicated CO edges
393 Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
394 // duplicate the EXDC Ntk
395 if ( pNtk->pExdc )
396 printf( "Warning: The EXDc network is skipped.\n" );
397 if ( !Abc_NtkCheck( pNtkNew ) )
398 fprintf( stdout, "Abc_NtkAigToLogicSopBench(): Network check has failed.\n" );
399 return pNtkNew;
400 }
401
402 /**Function*************************************************************
403
404 Synopsis [Converts the AIG into the logic network with SOPs for bench writing.]
405
406 Description [This procedure does not copy the choices.]
407
408 SideEffects []
409
410 SeeAlso []
411
412 ***********************************************************************/
Abc_NtkAigToLogicSopNand(Abc_Ntk_t * pNtk)413 Abc_Ntk_t * Abc_NtkAigToLogicSopNand( Abc_Ntk_t * pNtk )
414 {
415 Abc_Ntk_t * pNtkNew;
416 Abc_Obj_t * pObj, * pFanin;
417 Vec_Ptr_t * vNodes;
418 int i, k;
419 assert( Abc_NtkIsStrash(pNtk) );
420 if ( Abc_NtkGetChoiceNum(pNtk) )
421 printf( "Warning: Choice nodes are skipped.\n" );
422 // convert complemented edges
423 Abc_NtkForEachObj( pNtk, pObj, i )
424 Abc_ObjForEachFanin( pObj, pFanin, k )
425 if ( Abc_ObjIsNode(pFanin) )
426 Abc_ObjXorFaninC( pObj, k );
427 // start the network
428 pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_SOP );
429 // collect the nodes to be used (marks all nodes with current TravId)
430 vNodes = Abc_NtkDfs( pNtk, 0 );
431 // create inverters for the constant node
432 pObj = Abc_AigConst1(pNtk);
433 if ( Abc_ObjFanoutNum(pObj) > 0 )
434 pObj->pCopy = Abc_NtkCreateNodeConst1(pNtkNew);
435 if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
436 pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
437 // create inverters for the CIs
438 Abc_NtkForEachCi( pNtk, pObj, i )
439 if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
440 pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
441 // duplicate the nodes, create node functions, and inverters
442 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
443 {
444 Abc_NtkDupObj( pNtkNew, pObj, 0 );
445 pObj->pCopy->pData = Abc_SopCreateNand( (Mem_Flex_t *)pNtkNew->pManFunc, 2 );
446 if ( Abc_AigNodeHasComplFanoutEdgeTrav(pObj) )
447 pObj->pCopy->pCopy = Abc_NtkCreateNodeInv( pNtkNew, pObj->pCopy );
448 }
449 // connect the objects
450 Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
451 Abc_ObjForEachFanin( pObj, pFanin, k )
452 {
453 if ( Abc_ObjFaninC( pObj, k ) )
454 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy->pCopy );
455 else
456 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
457 }
458 Vec_PtrFree( vNodes );
459 // connect the COs
460 Abc_NtkForEachCo( pNtk, pObj, i )
461 {
462 pFanin = Abc_ObjFanin0(pObj);
463 if ( Abc_ObjFaninC0( pObj ) )
464 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy->pCopy );
465 else
466 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
467 }
468 // fix the problem with complemented and duplicated CO edges
469 Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
470 // convert complemented edges
471 Abc_NtkForEachObj( pNtk, pObj, i )
472 Abc_ObjForEachFanin( pObj, pFanin, k )
473 if ( Abc_ObjIsNode(pFanin) )
474 Abc_ObjXorFaninC( pObj, k );
475 // duplicate the EXDC Ntk
476 if ( pNtk->pExdc )
477 printf( "Warning: The EXDc network is skipped.\n" );
478 if ( !Abc_NtkCheck( pNtkNew ) )
479 fprintf( stdout, "Abc_NtkAigToLogicSopBench(): Network check has failed.\n" );
480 return pNtkNew;
481 }
482
483 /**Function*************************************************************
484
485 Synopsis [Adds buffers for each PO.]
486
487 Description []
488
489 SideEffects []
490
491 SeeAlso []
492
493 ***********************************************************************/
Abc_NtkAddPoBuffers(Abc_Ntk_t * pNtk)494 void Abc_NtkAddPoBuffers( Abc_Ntk_t * pNtk )
495 {
496 Abc_Obj_t * pObj, * pFanin, * pFaninNew;
497 int i;
498 assert( Abc_NtkIsStrash(pNtk) );
499 Abc_NtkForEachPo( pNtk, pObj, i )
500 {
501 pFanin = Abc_ObjChild0(pObj);
502 pFaninNew = Abc_NtkCreateNode(pNtk);
503 Abc_ObjAddFanin( pFaninNew, pFanin );
504 Abc_ObjPatchFanin( pObj, pFanin, pFaninNew );
505 }
506 }
507
508 ////////////////////////////////////////////////////////////////////////
509 /// END OF FILE ///
510 ////////////////////////////////////////////////////////////////////////
511
512
513 ABC_NAMESPACE_IMPL_END
514
515