1 /**CFile****************************************************************
2
3 FileName [abcHie.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [Network and node package.]
8
9 Synopsis [Procedures to handle hierarchy.]
10
11 Author [Alan Mishchenko]
12
13 Affiliation [UC Berkeley]
14
15 Date [Ver. 1.0. Started - June 20, 2005.]
16
17 Revision [$Id: abcHie.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 [Recursively flattens logic hierarchy of the netlist.]
37
38 Description [When this procedure is called, the PI/PO nets of the old
39 netlist point to the corresponding nets of the flattened netlist.]
40
41 SideEffects []
42
43 SeeAlso []
44
45 ***********************************************************************/
Abc_NtkFlattenLogicHierarchy2_rec(Abc_Ntk_t * pNtkNew,Abc_Ntk_t * pNtk,int * pCounter)46 void Abc_NtkFlattenLogicHierarchy2_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, int * pCounter )
47 {
48 char Suffix[2000] = {0};
49 Abc_Ntk_t * pNtkModel;
50 Abc_Obj_t * pObj, * pTerm, * pNet, * pFanin;
51 int i, k;
52
53 // process the blackbox
54 if ( Abc_NtkHasBlackbox(pNtk) )
55 {
56 // duplicate the blackbox
57 assert( Abc_NtkBoxNum(pNtk) == 1 );
58 pObj = Abc_NtkBox( pNtk, 0 );
59 Abc_NtkDupBox( pNtkNew, pObj, 1 );
60 pObj->pCopy->pData = pNtk;
61
62 // connect blackbox fanins to the PI nets
63 assert( Abc_ObjFaninNum(pObj->pCopy) == Abc_NtkPiNum(pNtk) );
64 Abc_NtkForEachPi( pNtk, pTerm, i )
65 Abc_ObjAddFanin( Abc_ObjFanin(pObj->pCopy,i), Abc_ObjFanout0(pTerm)->pCopy );
66
67 // connect blackbox fanouts to the PO nets
68 assert( Abc_ObjFanoutNum(pObj->pCopy) == Abc_NtkPoNum(pNtk) );
69 Abc_NtkForEachPo( pNtk, pTerm, i )
70 Abc_ObjAddFanin( Abc_ObjFanin0(pTerm)->pCopy, Abc_ObjFanout(pObj->pCopy,i) );
71 return;
72 }
73
74 (*pCounter)++;
75
76 // create the suffix, which will be appended to the internal names
77 if ( *pCounter )
78 sprintf( Suffix, "_%s_%d", Abc_NtkName(pNtk), *pCounter );
79
80 // duplicate nets of all boxes, including latches
81 Abc_NtkForEachBox( pNtk, pObj, i )
82 {
83 Abc_ObjForEachFanin( pObj, pTerm, k )
84 {
85 pNet = Abc_ObjFanin0(pTerm);
86 if ( pNet->pCopy )
87 continue;
88 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjNameSuffix(pNet, Suffix) );
89 }
90 Abc_ObjForEachFanout( pObj, pTerm, k )
91 {
92 pNet = Abc_ObjFanout0(pTerm);
93 if ( pNet->pCopy )
94 continue;
95 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjNameSuffix(pNet, Suffix) );
96 }
97 }
98
99 // mark objects that will not be used
100 Abc_NtkIncrementTravId( pNtk );
101 Abc_NtkForEachPi( pNtk, pTerm, i )
102 Abc_NodeSetTravIdCurrent( pTerm );
103 Abc_NtkForEachPo( pNtk, pTerm, i )
104 {
105 Abc_NodeSetTravIdCurrent( pTerm );
106 // if the netlist has net names beginning with "abc_property_"
107 // these names will be addes as primary outputs of the network
108 pNet = Abc_ObjFanin0(pTerm);
109 if ( strncmp( Abc_ObjName(pNet), "abc_property", 12 ) )
110 continue;
111 Abc_ObjAddFanin( Abc_NtkCreatePo(pNet->pCopy->pNtk), pNet->pCopy );
112 if ( Nm_ManFindNameById(pNet->pCopy->pNtk->pManName, pNet->pCopy->Id) )
113 Nm_ManDeleteIdName(pNet->pCopy->pNtk->pManName, pNet->pCopy->Id);
114 Abc_ObjAssignName( pNet->pCopy, Abc_ObjName(pNet), Suffix );
115 }
116 Abc_NtkForEachBox( pNtk, pObj, i )
117 {
118 if ( Abc_ObjIsLatch(pObj) )
119 continue;
120 Abc_NodeSetTravIdCurrent( pObj );
121 Abc_ObjForEachFanin( pObj, pTerm, k )
122 Abc_NodeSetTravIdCurrent( pTerm );
123 Abc_ObjForEachFanout( pObj, pTerm, k )
124 Abc_NodeSetTravIdCurrent( pTerm );
125 }
126
127 // duplicate objects that do not have prototypes yet
128 Abc_NtkForEachObj( pNtk, pObj, i )
129 {
130 if ( Abc_NodeIsTravIdCurrent(pObj) )
131 continue;
132 if ( pObj->pCopy )
133 continue;
134 Abc_NtkDupObj( pNtkNew, pObj, 0 );
135 }
136
137 // connect objects
138 Abc_NtkForEachObj( pNtk, pObj, i )
139 if ( !Abc_NodeIsTravIdCurrent(pObj) )
140 Abc_ObjForEachFanin( pObj, pFanin, k )
141 if ( !Abc_NodeIsTravIdCurrent(pFanin) )
142 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
143
144 // call recursively
145 Abc_NtkForEachBox( pNtk, pObj, i )
146 {
147 if ( Abc_ObjIsLatch(pObj) )
148 continue;
149 pNtkModel = (Abc_Ntk_t *)pObj->pData;
150 // check the match between the number of actual and formal parameters
151 assert( Abc_ObjFaninNum(pObj) == Abc_NtkPiNum(pNtkModel) );
152 assert( Abc_ObjFanoutNum(pObj) == Abc_NtkPoNum(pNtkModel) );
153 // clean the node copy fields
154 Abc_NtkCleanCopy( pNtkModel );
155 // map PIs/POs
156 Abc_ObjForEachFanin( pObj, pTerm, k )
157 Abc_ObjFanout0( Abc_NtkPi(pNtkModel, k) )->pCopy = Abc_ObjFanin0(pTerm)->pCopy;
158 Abc_ObjForEachFanout( pObj, pTerm, k )
159 Abc_ObjFanin0( Abc_NtkPo(pNtkModel, k) )->pCopy = Abc_ObjFanout0(pTerm)->pCopy;
160 // call recursively
161 Abc_NtkFlattenLogicHierarchy2_rec( pNtkNew, pNtkModel, pCounter );
162 }
163
164 // if it is a BLIF-MV netlist transfer the values of all nets
165 if ( Abc_NtkHasBlifMv(pNtk) && Abc_NtkMvVar(pNtk) )
166 {
167 if ( Abc_NtkMvVar( pNtkNew ) == NULL )
168 Abc_NtkStartMvVars( pNtkNew );
169 Abc_NtkForEachNet( pNtk, pObj, i )
170 Abc_NtkSetMvVarValues( pObj->pCopy, Abc_ObjMvVarNum(pObj) );
171 }
172 }
173
174 /**Function*************************************************************
175
176 Synopsis [Flattens the logic hierarchy of the netlist.]
177
178 Description []
179
180 SideEffects []
181
182 SeeAlso []
183
184 ***********************************************************************/
Abc_NtkFlattenLogicHierarchy2(Abc_Ntk_t * pNtk)185 Abc_Ntk_t * Abc_NtkFlattenLogicHierarchy2( Abc_Ntk_t * pNtk )
186 {
187 Abc_Ntk_t * pNtkNew;
188 Abc_Obj_t * pTerm, * pNet;
189 int i, Counter;
190 extern Abc_Des_t * Abc_DesDupBlackboxes( Abc_Des_t * p, Abc_Ntk_t * pNtkSave );
191
192 assert( Abc_NtkIsNetlist(pNtk) );
193 // start the network
194 pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
195 // duplicate the name and the spec
196 pNtkNew->pName = Abc_UtilStrsav(pNtk->pName);
197 pNtkNew->pSpec = Abc_UtilStrsav(pNtk->pSpec);
198
199 // clean the node copy fields
200 Abc_NtkCleanCopy( pNtk );
201
202 // duplicate PIs/POs and their nets
203 Abc_NtkForEachPi( pNtk, pTerm, i )
204 {
205 Abc_NtkDupObj( pNtkNew, pTerm, 0 );
206 pNet = Abc_ObjFanout0( pTerm );
207 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNet) );
208 Abc_ObjAddFanin( pNet->pCopy, pTerm->pCopy );
209 }
210 Abc_NtkForEachPo( pNtk, pTerm, i )
211 {
212 Abc_NtkDupObj( pNtkNew, pTerm, 0 );
213 pNet = Abc_ObjFanin0( pTerm );
214 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNet) );
215 Abc_ObjAddFanin( pTerm->pCopy, pNet->pCopy );
216 }
217
218 // recursively flatten hierarchy, create internal logic, add new PI/PO names if there are black boxes
219 Counter = -1;
220 Abc_NtkFlattenLogicHierarchy2_rec( pNtkNew, pNtk, &Counter );
221 printf( "Hierarchy reader flattened %d instances of logic boxes and left %d black boxes.\n",
222 Counter, Abc_NtkBlackboxNum(pNtkNew) );
223
224 if ( pNtk->pDesign )
225 {
226 // pass on the design
227 assert( Vec_PtrEntry(pNtk->pDesign->vTops, 0) == pNtk );
228 pNtkNew->pDesign = Abc_DesDupBlackboxes( pNtk->pDesign, pNtkNew );
229 // update the pointers
230 Abc_NtkForEachBlackbox( pNtkNew, pTerm, i )
231 pTerm->pData = ((Abc_Ntk_t *)pTerm->pData)->pCopy;
232 }
233
234 // we may have added property outputs
235 Abc_NtkOrderCisCos( pNtkNew );
236
237 // copy the timing information
238 // Abc_ManTimeDup( pNtk, pNtkNew );
239 // duplicate EXDC
240 if ( pNtk->pExdc )
241 printf( "EXDC is not transformed.\n" );
242 if ( !Abc_NtkCheck( pNtkNew ) )
243 {
244 fprintf( stdout, "Abc_NtkFlattenLogicHierarchy2(): Network check has failed.\n" );
245 Abc_NtkDelete( pNtkNew );
246 return NULL;
247 }
248 return pNtkNew;
249 }
250
251
252
253 /**Function*************************************************************
254
255 Synopsis [Recursively flattens logic hierarchy of the netlist.]
256
257 Description [When this procedure is called, the PI/PO nets of the old
258 netlist point to the corresponding nets of the flattened netlist.]
259
260 SideEffects []
261
262 SeeAlso []
263
264 ***********************************************************************/
Abc_NtkFlattenLogicHierarchy_rec(Abc_Ntk_t * pNtkNew,Abc_Ntk_t * pNtk,int * pCounter,Vec_Str_t * vPref)265 void Abc_NtkFlattenLogicHierarchy_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, int * pCounter, Vec_Str_t * vPref )
266 {
267 Abc_Ntk_t * pNtkModel;
268 Abc_Obj_t * pObj, * pTerm, * pNet, * pFanin;
269 int i, k, Length;
270
271 // process the blackbox
272 if ( Abc_NtkHasBlackbox(pNtk) )
273 {
274 //printf( "Flatting black box \"%s\".\n", pNtk->pName );
275 // duplicate the blackbox
276 assert( Abc_NtkBoxNum(pNtk) == 1 );
277 pObj = Abc_NtkBox( pNtk, 0 );
278 Abc_NtkDupBox( pNtkNew, pObj, 1 );
279 pObj->pCopy->pData = pNtk;
280
281 // connect blackbox fanins to the PI nets
282 assert( Abc_ObjFaninNum(pObj->pCopy) == Abc_NtkPiNum(pNtk) );
283 Abc_NtkForEachPi( pNtk, pTerm, i )
284 Abc_ObjAddFanin( Abc_ObjFanin(pObj->pCopy,i), Abc_ObjFanout0(pTerm)->pCopy );
285
286 // connect blackbox fanouts to the PO nets
287 assert( Abc_ObjFanoutNum(pObj->pCopy) == Abc_NtkPoNum(pNtk) );
288 Abc_NtkForEachPo( pNtk, pTerm, i )
289 Abc_ObjAddFanin( Abc_ObjFanin0(pTerm)->pCopy, Abc_ObjFanout(pObj->pCopy,i) );
290 return;
291 }
292
293 (*pCounter)++;
294
295 // create the suffix, which will be appended to the internal names
296 if ( *pCounter )
297 {
298 char Buffer[20];
299 sprintf( Buffer, "(%d)", *pCounter );
300 Vec_StrPrintStr( vPref, Buffer );
301 }
302 Vec_StrPush( vPref, '|' );
303 Vec_StrPush( vPref, 0 );
304
305 // duplicate nets of all boxes, including latches
306 Abc_NtkForEachBox( pNtk, pObj, i )
307 {
308 Abc_ObjForEachFanin( pObj, pTerm, k )
309 {
310 pNet = Abc_ObjFanin0(pTerm);
311 if ( pNet->pCopy )
312 continue;
313 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjNamePrefix(pNet, Vec_StrArray(vPref)) );
314 }
315 Abc_ObjForEachFanout( pObj, pTerm, k )
316 {
317 pNet = Abc_ObjFanout0(pTerm);
318 if ( pNet->pCopy )
319 continue;
320 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjNamePrefix(pNet, Vec_StrArray(vPref)) );
321 }
322 }
323
324 // mark objects that will not be used
325 Abc_NtkIncrementTravId( pNtk );
326 Abc_NtkForEachPi( pNtk, pTerm, i )
327 Abc_NodeSetTravIdCurrent( pTerm );
328 Abc_NtkForEachPo( pNtk, pTerm, i )
329 {
330 Abc_NodeSetTravIdCurrent( pTerm );
331 // if the netlist has net names beginning with "abc_property_"
332 // these names will be addes as primary outputs of the network
333 pNet = Abc_ObjFanin0(pTerm);
334 if ( strncmp( Abc_ObjName(pNet), "abc_property", 12 ) )
335 continue;
336 Abc_ObjAddFanin( Abc_NtkCreatePo(pNet->pCopy->pNtk), pNet->pCopy );
337 if ( Nm_ManFindNameById(pNet->pCopy->pNtk->pManName, pNet->pCopy->Id) )
338 Nm_ManDeleteIdName(pNet->pCopy->pNtk->pManName, pNet->pCopy->Id);
339 Abc_ObjAssignName( pNet->pCopy, Vec_StrArray(vPref), Abc_ObjName(pNet) );
340 }
341 Abc_NtkForEachBox( pNtk, pObj, i )
342 {
343 if ( Abc_ObjIsLatch(pObj) )
344 continue;
345 Abc_NodeSetTravIdCurrent( pObj );
346 Abc_ObjForEachFanin( pObj, pTerm, k )
347 Abc_NodeSetTravIdCurrent( pTerm );
348 Abc_ObjForEachFanout( pObj, pTerm, k )
349 Abc_NodeSetTravIdCurrent( pTerm );
350 }
351
352 // duplicate objects that do not have prototypes yet
353 Abc_NtkForEachObj( pNtk, pObj, i )
354 {
355 if ( Abc_NodeIsTravIdCurrent(pObj) )
356 continue;
357 if ( pObj->pCopy )
358 continue;
359 Abc_NtkDupObj( pNtkNew, pObj, 0 );
360 }
361
362 // connect objects
363 Abc_NtkForEachObj( pNtk, pObj, i )
364 if ( !Abc_NodeIsTravIdCurrent(pObj) )
365 Abc_ObjForEachFanin( pObj, pFanin, k )
366 if ( !Abc_NodeIsTravIdCurrent(pFanin) )
367 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
368
369 // call recursively
370 Vec_StrPop( vPref );
371 Length = Vec_StrSize( vPref );
372 Abc_NtkForEachBox( pNtk, pObj, i )
373 {
374 if ( Abc_ObjIsLatch(pObj) )
375 continue;
376 pNtkModel = (Abc_Ntk_t *)pObj->pData;
377 // check the match between the number of actual and formal parameters
378 assert( Abc_ObjFaninNum(pObj) == Abc_NtkPiNum(pNtkModel) );
379 assert( Abc_ObjFanoutNum(pObj) == Abc_NtkPoNum(pNtkModel) );
380 // clean the node copy fields
381 Abc_NtkCleanCopy( pNtkModel );
382 // map PIs/POs
383 Abc_ObjForEachFanin( pObj, pTerm, k )
384 Abc_ObjFanout0( Abc_NtkPi(pNtkModel, k) )->pCopy = Abc_ObjFanin0(pTerm)->pCopy;
385 Abc_ObjForEachFanout( pObj, pTerm, k )
386 Abc_ObjFanin0( Abc_NtkPo(pNtkModel, k) )->pCopy = Abc_ObjFanout0(pTerm)->pCopy;
387 // create name
388 Vec_StrShrink( vPref, Length );
389 Vec_StrPrintStr( vPref, Abc_NtkName(pNtkModel) );
390 // call recursively
391 Abc_NtkFlattenLogicHierarchy_rec( pNtkNew, pNtkModel, pCounter, vPref );
392 }
393
394 // if it is a BLIF-MV netlist transfer the values of all nets
395 if ( Abc_NtkHasBlifMv(pNtk) && Abc_NtkMvVar(pNtk) )
396 {
397 if ( Abc_NtkMvVar( pNtkNew ) == NULL )
398 Abc_NtkStartMvVars( pNtkNew );
399 Abc_NtkForEachNet( pNtk, pObj, i )
400 Abc_NtkSetMvVarValues( pObj->pCopy, Abc_ObjMvVarNum(pObj) );
401 }
402 }
403
404 /**Function*************************************************************
405
406 Synopsis [Returns 0 if CI names are repeated.]
407
408 Description []
409
410 SideEffects []
411
412 SeeAlso []
413
414 ***********************************************************************/
Abc_NtkCompareNames(Abc_Ntk_t ** p1,Abc_Ntk_t ** p2)415 int Abc_NtkCompareNames( Abc_Ntk_t ** p1, Abc_Ntk_t ** p2 )
416 {
417 return strcmp( Abc_NtkName(*p1), Abc_NtkName(*p2) );
418 }
419
420 /**Function*************************************************************
421
422 Synopsis [Prints information about boxes.]
423
424 Description []
425
426 SideEffects []
427
428 SeeAlso []
429
430 ***********************************************************************/
Abc_NtkPrintBoxInfo(Abc_Ntk_t * pNtk)431 void Abc_NtkPrintBoxInfo( Abc_Ntk_t * pNtk )
432 {
433 Vec_Ptr_t * vMods;
434 Abc_Ntk_t * pModel, * pBoxModel;
435 Abc_Obj_t * pObj;
436 Vec_Int_t * vCounts;
437 int i, k, Num;
438 if ( pNtk->pDesign == NULL || pNtk->pDesign->vModules == NULL )
439 {
440 // printf( "There is no hierarchy information.\n" );
441 return;
442 }
443 // sort models by name
444 vMods = pNtk->pDesign->vModules;
445 Vec_PtrSort( vMods, (int(*)())Abc_NtkCompareNames );
446 // Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
447 // printf( "%s\n", Abc_NtkName(pModel) );
448
449 // swap the first model
450 Num = Vec_PtrFind( vMods, pNtk );
451 assert( Num >= 0 && Num < Vec_PtrSize(vMods) );
452 pBoxModel = (Abc_Ntk_t *)Vec_PtrEntry(vMods, 0);
453 Vec_PtrWriteEntry(vMods, 0, (Abc_Ntk_t *)Vec_PtrEntry(vMods, Num) );
454 Vec_PtrWriteEntry(vMods, Num, pBoxModel );
455
456 // print models
457 vCounts = Vec_IntStart( Vec_PtrSize(vMods) );
458 Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
459 {
460 if ( Abc_NtkBoxNum(pModel) == 0 )
461 continue;
462 Vec_IntFill( vCounts, Vec_IntSize(vCounts), 0 );
463 Abc_NtkForEachBox( pModel, pObj, k )
464 {
465 pBoxModel = (Abc_Ntk_t *)pObj->pData;
466 if ( pBoxModel == NULL )
467 continue;
468 Num = Vec_PtrFind( vMods, pBoxModel );
469 assert( Num >= 0 && Num < Vec_PtrSize(vMods) );
470 Vec_IntAddToEntry( vCounts, Num, 1 );
471 }
472
473 // Abc_NtkPrintStats( pModel, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
474 printf( "MODULE " );
475 printf( "%-30s : ", Abc_NtkName(pModel) );
476 printf( "PI=%6d ", Abc_NtkPiNum(pModel) );
477 printf( "PO=%6d ", Abc_NtkPoNum(pModel) );
478 printf( "BB=%6d ", Abc_NtkBoxNum(pModel) );
479 printf( "ND=%6d ", Abc_NtkNodeNum(pModel) ); // sans constants
480 printf( "Lev=%5d ", Abc_NtkLevel(pModel) );
481 printf( "\n" );
482
483 Vec_IntForEachEntry( vCounts, Num, k )
484 if ( Num )
485 printf( "%15d : %s\n", Num, Abc_NtkName((Abc_Ntk_t *)Vec_PtrEntry(vMods, k)) );
486 }
487 Vec_IntFree( vCounts );
488 Vec_PtrForEachEntry( Abc_Ntk_t *, vMods, pModel, i )
489 {
490 if ( Abc_NtkBoxNum(pModel) != 0 )
491 continue;
492 printf( "MODULE " );
493 printf( "%-30s : ", Abc_NtkName(pModel) );
494 printf( "PI=%6d ", Abc_NtkPiNum(pModel) );
495 printf( "PO=%6d ", Abc_NtkPoNum(pModel) );
496 printf( "BB=%6d ", Abc_NtkBoxNum(pModel) );
497 printf( "ND=%6d ", Abc_NtkNodeNum(pModel) );
498 printf( "Lev=%5d ", Abc_NtkLevel(pModel) );
499 printf( "\n" );
500 }
501 }
502
503 /**Function*************************************************************
504
505 Synopsis [Flattens the logic hierarchy of the netlist.]
506
507 Description []
508
509 SideEffects []
510
511 SeeAlso []
512
513 ***********************************************************************/
Abc_NtkFlattenLogicHierarchy(Abc_Ntk_t * pNtk)514 Abc_Ntk_t * Abc_NtkFlattenLogicHierarchy( Abc_Ntk_t * pNtk )
515 {
516 extern Abc_Des_t * Abc_DesDupBlackboxes( Abc_Des_t * p, Abc_Ntk_t * pNtkSave );
517 Vec_Str_t * vPref;
518 Abc_Ntk_t * pNtkNew;
519 Abc_Obj_t * pTerm, * pNet;
520 int i, Counter = -1;
521
522 assert( Abc_NtkIsNetlist(pNtk) );
523 // Abc_NtkPrintBoxInfo( pNtk );
524
525 // start the network
526 pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
527 // duplicate the name and the spec
528 pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
529 pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
530
531 // clean the node copy fields
532 Abc_NtkCleanCopy( pNtk );
533
534 // duplicate PIs/POs and their nets
535 Abc_NtkForEachPi( pNtk, pTerm, i )
536 {
537 Abc_NtkDupObj( pNtkNew, pTerm, 0 );
538 pNet = Abc_ObjFanout0( pTerm );
539 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNet) );
540 Abc_ObjAddFanin( pNet->pCopy, pTerm->pCopy );
541 }
542 Abc_NtkForEachPo( pNtk, pTerm, i )
543 {
544 Abc_NtkDupObj( pNtkNew, pTerm, 0 );
545 pNet = Abc_ObjFanin0( pTerm );
546 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNet) );
547 Abc_ObjAddFanin( pTerm->pCopy, pNet->pCopy );
548 }
549
550 // recursively flatten hierarchy, create internal logic, add new PI/PO names if there are black boxes
551 vPref = Vec_StrAlloc( 1000 );
552 Vec_StrPrintStr( vPref, Abc_NtkName(pNtk) );
553 Abc_NtkFlattenLogicHierarchy_rec( pNtkNew, pNtk, &Counter, vPref );
554 printf( "Hierarchy reader flattened %d instances of logic boxes and left %d black boxes.\n",
555 Counter, Abc_NtkBlackboxNum(pNtkNew) );
556 Vec_StrFree( vPref );
557
558 if ( pNtk->pDesign )
559 {
560 // pass on the design
561 assert( Vec_PtrEntry(pNtk->pDesign->vTops, 0) == pNtk );
562 pNtkNew->pDesign = Abc_DesDupBlackboxes( pNtk->pDesign, pNtkNew );
563 // update the pointers
564 Abc_NtkForEachBlackbox( pNtkNew, pTerm, i )
565 pTerm->pData = ((Abc_Ntk_t *)pTerm->pData)->pCopy;
566 }
567
568 // we may have added property outputs
569 Abc_NtkOrderCisCos( pNtkNew );
570
571 // copy the timing information
572 // Abc_ManTimeDup( pNtk, pNtkNew );
573 // duplicate EXDC
574 if ( pNtk->pExdc )
575 printf( "EXDC is not transformed.\n" );
576 if ( !Abc_NtkCheck( pNtkNew ) )
577 {
578 fprintf( stdout, "Abc_NtkFlattenLogicHierarchy(): Network check has failed.\n" );
579 Abc_NtkDelete( pNtkNew );
580 return NULL;
581 }
582 return pNtkNew;
583 }
584
585
586 /**Function*************************************************************
587
588 Synopsis [Extracts blackboxes by making them into additional PIs/POs.]
589
590 Description [The input netlist has not logic hierarchy. The resulting
591 netlist has additional PIs/POs for each blackbox input/output.]
592
593 SideEffects []
594
595 SeeAlso []
596
597 ***********************************************************************/
Abc_NtkConvertBlackboxes(Abc_Ntk_t * pNtk)598 Abc_Ntk_t * Abc_NtkConvertBlackboxes( Abc_Ntk_t * pNtk )
599 {
600 Abc_Ntk_t * pNtkNew;
601 Abc_Obj_t * pObj, * pNet, * pFanin, * pTerm;
602 int i, k;
603
604 assert( Abc_NtkIsNetlist(pNtk) );
605 assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
606
607 // start the network
608 pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
609 // duplicate the name and the spec
610 pNtkNew->pName = Extra_UtilStrsav( pNtk->pName );
611 pNtkNew->pSpec = Extra_UtilStrsav( pNtk->pSpec );
612
613 // clean the node copy fields
614 Abc_NtkCleanCopy( pNtk );
615
616 // mark the nodes that should not be connected
617 Abc_NtkIncrementTravId( pNtk );
618 Abc_NtkForEachBlackbox( pNtk, pObj, i )
619 Abc_NodeSetTravIdCurrent( pObj );
620 Abc_NtkForEachCi( pNtk, pTerm, i )
621 Abc_NodeSetTravIdCurrent( pTerm );
622 Abc_NtkForEachCo( pNtk, pTerm, i )
623 Abc_NodeSetTravIdCurrent( pTerm );
624 // unmark PIs and LIs/LOs
625 Abc_NtkForEachPi( pNtk, pTerm, i )
626 Abc_NodeSetTravIdPrevious( pTerm );
627 Abc_NtkForEachLatchInput( pNtk, pTerm, i )
628 Abc_NodeSetTravIdPrevious( pTerm );
629 Abc_NtkForEachLatchOutput( pNtk, pTerm, i )
630 Abc_NodeSetTravIdPrevious( pTerm );
631 // copy the box outputs
632 Abc_NtkForEachBlackbox( pNtk, pObj, i )
633 Abc_ObjForEachFanout( pObj, pTerm, k )
634 pTerm->pCopy = Abc_NtkCreatePi( pNtkNew );
635
636 // duplicate other objects
637 Abc_NtkForEachObj( pNtk, pObj, i )
638 if ( !Abc_NodeIsTravIdCurrent(pObj) )
639 Abc_NtkDupObj( pNtkNew, pObj, Abc_ObjIsNet(pObj) );
640
641 // connect all objects
642 Abc_NtkForEachObj( pNtk, pObj, i )
643 if ( !Abc_NodeIsTravIdCurrent(pObj) )
644 Abc_ObjForEachFanin( pObj, pFanin, k )
645 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
646
647 // create unique PO for each net feeding into blackboxes or POs
648 Abc_NtkIncrementTravId( pNtk );
649 Abc_NtkForEachCo( pNtk, pTerm, i )
650 {
651 // skip latch inputs
652 assert( Abc_ObjFanoutNum(pTerm) <= 1 );
653 if ( Abc_ObjFanoutNum(pTerm) > 0 && Abc_ObjIsLatch(Abc_ObjFanout0(pTerm)) )
654 continue;
655 // check if the net is visited
656 pNet = Abc_ObjFanin0(pTerm);
657 if ( Abc_NodeIsTravIdCurrent(pNet) )
658 continue;
659 // create PO
660 Abc_NodeSetTravIdCurrent( pNet );
661 Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNet->pCopy );
662 }
663
664 // check integrity
665 if ( !Abc_NtkCheck( pNtkNew ) )
666 {
667 fprintf( stdout, "Abc_NtkConvertBlackboxes(): Network check has failed.\n" );
668 Abc_NtkDelete( pNtkNew );
669 return NULL;
670 }
671 return pNtkNew;
672 }
673
674 /**Function*************************************************************
675
676 Synopsis [Inserts blackboxes into the netlist.]
677
678 Description [The first arg is the netlist with blackboxes without logic hierarchy.
679 The second arg is a non-hierarchical netlist derived from the above netlist after processing.
680 This procedure create a new netlist, which is comparable to the original netlist with
681 blackboxes, except that it contains logic nodes from the netlist after processing.]
682
683 SideEffects [This procedure silently assumes that blackboxes appear
684 only in the top-level model. If they appear in other models as well,
685 the name of the model and its number were appended to the names of
686 blackbox inputs/outputs.]
687
688 SeeAlso []
689
690 ***********************************************************************/
Abc_NtkInsertNewLogic(Abc_Ntk_t * pNtkH,Abc_Ntk_t * pNtkL)691 Abc_Ntk_t * Abc_NtkInsertNewLogic( Abc_Ntk_t * pNtkH, Abc_Ntk_t * pNtkL )
692 {
693 Abc_Des_t * pDesign;
694 Abc_Ntk_t * pNtkNew;
695 Abc_Obj_t * pObjH, * pObjL, * pNetH, * pNetL, * pTermH;
696 int i, k;
697
698 assert( Abc_NtkIsNetlist(pNtkH) );
699 assert( Abc_NtkWhiteboxNum(pNtkH) == 0 );
700 assert( Abc_NtkBlackboxNum(pNtkH) > 0 );
701
702 assert( Abc_NtkIsNetlist(pNtkL) );
703 assert( Abc_NtkWhiteboxNum(pNtkL) == 0 );
704 assert( Abc_NtkBlackboxNum(pNtkL) == 0 );
705
706 // prepare the logic network for copying
707 Abc_NtkCleanCopy( pNtkL );
708
709 // start the network
710 pNtkNew = Abc_NtkAlloc( pNtkL->ntkType, pNtkL->ntkFunc, 1 );
711 // duplicate the name and the spec
712 pNtkNew->pName = Extra_UtilStrsav( pNtkH->pName );
713 pNtkNew->pSpec = Extra_UtilStrsav( pNtkH->pSpec );
714
715 // make sure every PI/PO has a PI/PO in the processed network
716 Abc_NtkForEachPi( pNtkH, pObjH, i )
717 {
718 pNetH = Abc_ObjFanout0(pObjH);
719 pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) );
720 if ( pNetL == NULL || !Abc_ObjIsPi( Abc_ObjFanin0(pNetL) ) )
721 {
722 printf( "Error in Abc_NtkInsertNewLogic(): There is no PI corresponding to the PI %s.\n", Abc_ObjName(pNetH) );
723 Abc_NtkDelete( pNtkNew );
724 return NULL;
725 }
726 if ( pNetL->pCopy )
727 {
728 printf( "Error in Abc_NtkInsertNewLogic(): Primary input %s is repeated twice.\n", Abc_ObjName(pNetH) );
729 Abc_NtkDelete( pNtkNew );
730 return NULL;
731 }
732 // create the new net
733 pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) );
734 Abc_NtkDupObj( pNtkNew, Abc_ObjFanin0(pNetL), 0 );
735 }
736
737 // make sure every BB has a PI/PO in the processed network
738 Abc_NtkForEachBlackbox( pNtkH, pObjH, i )
739 {
740 // duplicate the box
741 Abc_NtkDupBox( pNtkNew, pObjH, 0 );
742 pObjH->pCopy->pData = pObjH->pData;
743 // create PIs
744 Abc_ObjForEachFanout( pObjH, pTermH, k )
745 {
746 pNetH = Abc_ObjFanout0( pTermH );
747 pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) );
748 if ( pNetL == NULL || !Abc_ObjIsPi( Abc_ObjFanin0(pNetL) ) )
749 {
750 printf( "Error in Abc_NtkInsertNewLogic(): There is no PI corresponding to the inpout %s of blackbox %s.\n", Abc_ObjName(pNetH), Abc_ObjName(pObjH) );
751 Abc_NtkDelete( pNtkNew );
752 return NULL;
753 }
754 if ( pNetL->pCopy )
755 {
756 printf( "Error in Abc_NtkInsertNewLogic(): Box output %s is repeated twice.\n", Abc_ObjName(pNetH) );
757 Abc_NtkDelete( pNtkNew );
758 return NULL;
759 }
760 // create net and map the PI
761 pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) );
762 Abc_ObjFanin0(pNetL)->pCopy = pTermH->pCopy;
763 }
764 }
765
766 Abc_NtkForEachPo( pNtkH, pObjH, i )
767 {
768 pNetH = Abc_ObjFanin0(pObjH);
769 pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) );
770 if ( pNetL == NULL || !Abc_ObjIsPo( Abc_ObjFanout0(pNetL) ) )
771 {
772 printf( "Error in Abc_NtkInsertNewLogic(): There is no PO corresponding to the PO %s.\n", Abc_ObjName(pNetH) );
773 Abc_NtkDelete( pNtkNew );
774 return NULL;
775 }
776 if ( pNetL->pCopy )
777 continue;
778 // create the new net
779 pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) );
780 Abc_NtkDupObj( pNtkNew, Abc_ObjFanout0(pNetL), 0 );
781 }
782 Abc_NtkForEachBlackbox( pNtkH, pObjH, i )
783 {
784 Abc_ObjForEachFanin( pObjH, pTermH, k )
785 {
786 char * pName;
787 pNetH = Abc_ObjFanin0( pTermH );
788 pName = Abc_ObjName(pNetH);
789 pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) );
790 if ( pNetL == NULL || !Abc_ObjIsPo( Abc_ObjFanout0(pNetL) ) )
791 {
792 printf( "There is no PO corresponding to the input %s of blackbox %s.\n", Abc_ObjName(pNetH), Abc_ObjName(pObjH) );
793 Abc_NtkDelete( pNtkNew );
794 return NULL;
795 }
796 // create net and map the PO
797 if ( pNetL->pCopy )
798 {
799 if ( Abc_ObjFanout0(pNetL)->pCopy == NULL )
800 Abc_ObjFanout0(pNetL)->pCopy = pTermH->pCopy;
801 else
802 Abc_ObjAddFanin( pTermH->pCopy, pNetL->pCopy );
803 continue;
804 }
805 pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) );
806 Abc_ObjFanout0(pNetL)->pCopy = pTermH->pCopy;
807 }
808 }
809
810 // duplicate other objects of the logic network
811 Abc_NtkForEachObj( pNtkL, pObjL, i )
812 if ( pObjL->pCopy == NULL && !Abc_ObjIsPo(pObjL) ) // skip POs feeding into PIs
813 Abc_NtkDupObj( pNtkNew, pObjL, Abc_ObjIsNet(pObjL) );
814
815 // connect objects
816 Abc_NtkForEachObj( pNtkL, pObjL, i )
817 Abc_ObjForEachFanin( pObjL, pNetL, k )
818 if ( pObjL->pCopy )
819 Abc_ObjAddFanin( pObjL->pCopy, pNetL->pCopy );
820
821 // transfer the design
822 pDesign = pNtkH->pDesign; pNtkH->pDesign = NULL;
823 assert( Vec_PtrEntry( pDesign->vModules, 0 ) == pNtkH );
824 Vec_PtrWriteEntry( pDesign->vModules, 0, pNtkNew );
825 pNtkNew->pDesign = pDesign;
826
827 // check integrity
828 if ( !Abc_NtkCheck( pNtkNew ) )
829 {
830 fprintf( stdout, "Abc_NtkInsertNewLogic(): Network check has failed.\n" );
831 Abc_NtkDelete( pNtkNew );
832 return NULL;
833 }
834 return pNtkNew;
835 }
836
837 ////////////////////////////////////////////////////////////////////////
838 /// END OF FILE ///
839 ////////////////////////////////////////////////////////////////////////
840
841
842 ABC_NAMESPACE_IMPL_END
843
844