00001
00021 #include "abc.h"
00022
00026
00030
00043 void Abc_NtkFlattenLogicHierarchy_rec( Abc_Ntk_t * pNtkNew, Abc_Ntk_t * pNtk, int * pCounter )
00044 {
00045 char Suffix[1000] = {0};
00046 Abc_Ntk_t * pNtkModel;
00047 Abc_Obj_t * pObj, * pTerm, * pNet, * pFanin;
00048 int i, k;
00049
00050
00051 if ( Abc_NtkHasBlackbox(pNtk) )
00052 {
00053
00054 assert( Abc_NtkBoxNum(pNtk) == 1 );
00055 pObj = Abc_NtkBox( pNtk, 0 );
00056 Abc_NtkDupBox( pNtkNew, pObj, 1 );
00057 pObj->pCopy->pData = pNtk;
00058
00059
00060 assert( Abc_ObjFaninNum(pObj->pCopy) == Abc_NtkPiNum(pNtk) );
00061 Abc_NtkForEachPi( pNtk, pTerm, i )
00062 Abc_ObjAddFanin( Abc_ObjFanin(pObj->pCopy,i), Abc_ObjFanout0(pTerm)->pCopy );
00063
00064
00065 assert( Abc_ObjFanoutNum(pObj->pCopy) == Abc_NtkPoNum(pNtk) );
00066 Abc_NtkForEachPo( pNtk, pTerm, i )
00067 Abc_ObjAddFanin( Abc_ObjFanin0(pTerm)->pCopy, Abc_ObjFanout(pObj->pCopy,i) );
00068 return;
00069 }
00070
00071 (*pCounter)++;
00072
00073
00074 if ( *pCounter )
00075 sprintf( Suffix, "_%s_%d", Abc_NtkName(pNtk), *pCounter );
00076
00077
00078 Abc_NtkForEachBox( pNtk, pObj, i )
00079 {
00080 Abc_ObjForEachFanin( pObj, pTerm, k )
00081 {
00082 pNet = Abc_ObjFanin0(pTerm);
00083 if ( pNet->pCopy )
00084 continue;
00085 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjNameSuffix(pNet, Suffix) );
00086 }
00087 Abc_ObjForEachFanout( pObj, pTerm, k )
00088 {
00089 pNet = Abc_ObjFanout0(pTerm);
00090 if ( pNet->pCopy )
00091 continue;
00092 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjNameSuffix(pNet, Suffix) );
00093 }
00094 }
00095
00096
00097 Abc_NtkIncrementTravId( pNtk );
00098 Abc_NtkForEachPi( pNtk, pTerm, i )
00099 Abc_NodeSetTravIdCurrent( pTerm );
00100 Abc_NtkForEachPo( pNtk, pTerm, i )
00101 Abc_NodeSetTravIdCurrent( pTerm );
00102 Abc_NtkForEachBox( pNtk, pObj, i )
00103 {
00104 if ( Abc_ObjIsLatch(pObj) )
00105 continue;
00106 Abc_NodeSetTravIdCurrent( pObj );
00107 Abc_ObjForEachFanin( pObj, pTerm, k )
00108 Abc_NodeSetTravIdCurrent( pTerm );
00109 Abc_ObjForEachFanout( pObj, pTerm, k )
00110 Abc_NodeSetTravIdCurrent( pTerm );
00111 }
00112
00113
00114 Abc_NtkForEachObj( pNtk, pObj, i )
00115 {
00116 if ( Abc_NodeIsTravIdCurrent(pObj) )
00117 continue;
00118 if ( pObj->pCopy )
00119 continue;
00120 Abc_NtkDupObj( pNtkNew, pObj, 0 );
00121 }
00122
00123
00124 Abc_NtkForEachObj( pNtk, pObj, i )
00125 if ( !Abc_NodeIsTravIdCurrent(pObj) )
00126 Abc_ObjForEachFanin( pObj, pFanin, k )
00127 if ( !Abc_NodeIsTravIdCurrent(pFanin) )
00128 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
00129
00130
00131 Abc_NtkForEachBox( pNtk, pObj, i )
00132 {
00133 if ( Abc_ObjIsLatch(pObj) )
00134 continue;
00135 pNtkModel = pObj->pData;
00136
00137 assert( Abc_ObjFaninNum(pObj) == Abc_NtkPiNum(pNtkModel) );
00138 assert( Abc_ObjFanoutNum(pObj) == Abc_NtkPoNum(pNtkModel) );
00139
00140 Abc_NtkCleanCopy( pNtkModel );
00141
00142 Abc_ObjForEachFanin( pObj, pTerm, k )
00143 Abc_ObjFanout0( Abc_NtkPi(pNtkModel, k) )->pCopy = Abc_ObjFanin0(pTerm)->pCopy;
00144 Abc_ObjForEachFanout( pObj, pTerm, k )
00145 Abc_ObjFanin0( Abc_NtkPo(pNtkModel, k) )->pCopy = Abc_ObjFanout0(pTerm)->pCopy;
00146
00147 Abc_NtkFlattenLogicHierarchy_rec( pNtkNew, pNtkModel, pCounter );
00148 }
00149
00150
00151 if ( Abc_NtkHasBlifMv(pNtk) && Abc_NtkMvVar(pNtk) )
00152 {
00153 if ( Abc_NtkMvVar( pNtkNew ) == NULL )
00154 Abc_NtkStartMvVars( pNtkNew );
00155 Abc_NtkForEachNet( pNtk, pObj, i )
00156 Abc_NtkSetMvVarValues( pObj->pCopy, Abc_ObjMvVarNum(pObj) );
00157 }
00158 }
00159
00171 Abc_Ntk_t * Abc_NtkFlattenLogicHierarchy( Abc_Ntk_t * pNtk )
00172 {
00173 Abc_Ntk_t * pNtkNew;
00174 Abc_Obj_t * pTerm, * pNet;
00175 int i, Counter;
00176 extern Abc_Lib_t * Abc_LibDupBlackboxes( Abc_Lib_t * pLib, Abc_Ntk_t * pNtkSave );
00177
00178 assert( Abc_NtkIsNetlist(pNtk) );
00179
00180 pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
00181
00182 pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
00183 pNtkNew->pSpec = Extra_UtilStrsav(pNtk->pSpec);
00184
00185
00186 Abc_NtkCleanCopy( pNtk );
00187
00188
00189 Abc_NtkForEachPi( pNtk, pTerm, i )
00190 {
00191 Abc_NtkDupObj( pNtkNew, pTerm, 0 );
00192 pNet = Abc_ObjFanout0( pTerm );
00193 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNet) );
00194 Abc_ObjAddFanin( pNet->pCopy, pTerm->pCopy );
00195 }
00196 Abc_NtkForEachPo( pNtk, pTerm, i )
00197 {
00198 Abc_NtkDupObj( pNtkNew, pTerm, 0 );
00199 pNet = Abc_ObjFanin0( pTerm );
00200 pNet->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNet) );
00201 Abc_ObjAddFanin( pTerm->pCopy, pNet->pCopy );
00202 }
00203
00204
00205 Counter = -1;
00206 Abc_NtkFlattenLogicHierarchy_rec( pNtkNew, pNtk, &Counter );
00207 printf( "Hierarchy reader flattened %d instances of logic boxes and left %d black boxes.\n",
00208 Counter, Abc_NtkBlackboxNum(pNtkNew) );
00209
00210 if ( pNtk->pDesign )
00211 {
00212
00213 assert( Vec_PtrEntry(pNtk->pDesign->vTops, 0) == pNtk );
00214 pNtkNew->pDesign = Abc_LibDupBlackboxes( pNtk->pDesign, pNtkNew );
00215
00216 Abc_NtkForEachBlackbox( pNtkNew, pTerm, i )
00217 pTerm->pData = ((Abc_Ntk_t *)pTerm->pData)->pCopy;
00218 }
00219
00220
00221
00222
00223 if ( pNtk->pExdc )
00224 printf( "EXDC is not transformed.\n" );
00225 if ( !Abc_NtkCheck( pNtkNew ) )
00226 {
00227 fprintf( stdout, "Abc_NtkFlattenLogicHierarchy(): Network check has failed.\n" );
00228 Abc_NtkDelete( pNtkNew );
00229 return NULL;
00230 }
00231 return pNtkNew;
00232 }
00233
00246 Abc_Ntk_t * Abc_NtkConvertBlackboxes( Abc_Ntk_t * pNtk )
00247 {
00248 Abc_Ntk_t * pNtkNew;
00249 Abc_Obj_t * pObj, * pNet, * pFanin, * pTerm;
00250 int i, k;
00251
00252 assert( Abc_NtkIsNetlist(pNtk) );
00253 assert( Abc_NtkWhiteboxNum(pNtk) == 0 );
00254
00255
00256 pNtkNew = Abc_NtkAlloc( pNtk->ntkType, pNtk->ntkFunc, 1 );
00257
00258 pNtkNew->pName = Extra_UtilStrsav( pNtk->pName );
00259 pNtkNew->pSpec = Extra_UtilStrsav( pNtk->pSpec );
00260
00261
00262 Abc_NtkCleanCopy( pNtk );
00263
00264
00265 Abc_NtkIncrementTravId( pNtk );
00266 Abc_NtkForEachBlackbox( pNtk, pObj, i )
00267 Abc_NodeSetTravIdCurrent( pObj );
00268 Abc_NtkForEachCi( pNtk, pTerm, i )
00269 Abc_NodeSetTravIdCurrent( pTerm );
00270 Abc_NtkForEachCo( pNtk, pTerm, i )
00271 Abc_NodeSetTravIdCurrent( pTerm );
00272
00273 Abc_NtkForEachPi( pNtk, pTerm, i )
00274 Abc_NodeSetTravIdPrevious( pTerm );
00275 Abc_NtkForEachLatchInput( pNtk, pTerm, i )
00276 Abc_NodeSetTravIdPrevious( pTerm );
00277 Abc_NtkForEachLatchOutput( pNtk, pTerm, i )
00278 Abc_NodeSetTravIdPrevious( pTerm );
00279
00280 Abc_NtkForEachBlackbox( pNtk, pObj, i )
00281 Abc_ObjForEachFanout( pObj, pTerm, k )
00282 pTerm->pCopy = Abc_NtkCreatePi( pNtkNew );
00283
00284
00285 Abc_NtkForEachObj( pNtk, pObj, i )
00286 if ( !Abc_NodeIsTravIdCurrent(pObj) )
00287 Abc_NtkDupObj( pNtkNew, pObj, Abc_ObjIsNet(pObj) );
00288
00289
00290 Abc_NtkForEachObj( pNtk, pObj, i )
00291 if ( !Abc_NodeIsTravIdCurrent(pObj) )
00292 Abc_ObjForEachFanin( pObj, pFanin, k )
00293 Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
00294
00295
00296 Abc_NtkIncrementTravId( pNtk );
00297 Abc_NtkForEachCo( pNtk, pTerm, i )
00298 {
00299
00300 assert( Abc_ObjFanoutNum(pTerm) <= 1 );
00301 if ( Abc_ObjFanoutNum(pTerm) > 0 && Abc_ObjIsLatch(Abc_ObjFanout0(pTerm)) )
00302 continue;
00303
00304 pNet = Abc_ObjFanin0(pTerm);
00305 if ( Abc_NodeIsTravIdCurrent(pNet) )
00306 continue;
00307
00308 Abc_NodeSetTravIdCurrent( pNet );
00309 Abc_ObjAddFanin( Abc_NtkCreatePo(pNtkNew), pNet->pCopy );
00310 }
00311
00312
00313 if ( !Abc_NtkCheck( pNtkNew ) )
00314 {
00315 fprintf( stdout, "Abc_NtkConvertBlackboxes(): Network check has failed.\n" );
00316 Abc_NtkDelete( pNtkNew );
00317 return NULL;
00318 }
00319 return pNtkNew;
00320 }
00321
00339 Abc_Ntk_t * Abc_NtkInsertNewLogic( Abc_Ntk_t * pNtkH, Abc_Ntk_t * pNtkL )
00340 {
00341 Abc_Lib_t * pDesign;
00342 Abc_Ntk_t * pNtkNew;
00343 Abc_Obj_t * pObjH, * pObjL, * pNetH, * pNetL, * pTermH;
00344 int i, k;
00345
00346 assert( Abc_NtkIsNetlist(pNtkH) );
00347 assert( Abc_NtkWhiteboxNum(pNtkH) == 0 );
00348 assert( Abc_NtkBlackboxNum(pNtkH) > 0 );
00349
00350 assert( Abc_NtkIsNetlist(pNtkL) );
00351 assert( Abc_NtkWhiteboxNum(pNtkL) == 0 );
00352 assert( Abc_NtkBlackboxNum(pNtkL) == 0 );
00353
00354
00355 Abc_NtkCleanCopy( pNtkL );
00356
00357
00358 pNtkNew = Abc_NtkAlloc( pNtkL->ntkType, pNtkL->ntkFunc, 1 );
00359
00360 pNtkNew->pName = Extra_UtilStrsav( pNtkH->pName );
00361 pNtkNew->pSpec = Extra_UtilStrsav( pNtkH->pSpec );
00362
00363
00364 Abc_NtkForEachPi( pNtkH, pObjH, i )
00365 {
00366 pNetH = Abc_ObjFanout0(pObjH);
00367 pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) );
00368 if ( pNetL == NULL || !Abc_ObjIsPi( Abc_ObjFanin0(pNetL) ) )
00369 {
00370 printf( "Error in Abc_NtkInsertNewLogic(): There is no PI corresponding to the PI %s.\n", Abc_ObjName(pNetH) );
00371 Abc_NtkDelete( pNtkNew );
00372 return NULL;
00373 }
00374 if ( pNetL->pCopy )
00375 {
00376 printf( "Error in Abc_NtkInsertNewLogic(): Primary input %s is repeated twice.\n", Abc_ObjName(pNetH) );
00377 Abc_NtkDelete( pNtkNew );
00378 return NULL;
00379 }
00380
00381 pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) );
00382 Abc_NtkDupObj( pNtkNew, Abc_ObjFanin0(pNetL), 0 );
00383 }
00384
00385
00386 Abc_NtkForEachBlackbox( pNtkH, pObjH, i )
00387 {
00388
00389 Abc_NtkDupBox( pNtkNew, pObjH, 0 );
00390 pObjH->pCopy->pData = pObjH->pData;
00391
00392 Abc_ObjForEachFanout( pObjH, pTermH, k )
00393 {
00394 pNetH = Abc_ObjFanout0( pTermH );
00395 pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) );
00396 if ( pNetL == NULL || !Abc_ObjIsPi( Abc_ObjFanin0(pNetL) ) )
00397 {
00398 printf( "Error in Abc_NtkInsertNewLogic(): There is no PI corresponding to the inpout %s of blackbox %s.\n", Abc_ObjName(pNetH), Abc_ObjName(pObjH) );
00399 Abc_NtkDelete( pNtkNew );
00400 return NULL;
00401 }
00402 if ( pNetL->pCopy )
00403 {
00404 printf( "Error in Abc_NtkInsertNewLogic(): Box output %s is repeated twice.\n", Abc_ObjName(pNetH) );
00405 Abc_NtkDelete( pNtkNew );
00406 return NULL;
00407 }
00408
00409 pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) );
00410 Abc_ObjFanin0(pNetL)->pCopy = pTermH->pCopy;
00411 }
00412 }
00413
00414 Abc_NtkForEachPo( pNtkH, pObjH, i )
00415 {
00416 pNetH = Abc_ObjFanin0(pObjH);
00417 pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) );
00418 if ( pNetL == NULL || !Abc_ObjIsPo( Abc_ObjFanout0(pNetL) ) )
00419 {
00420 printf( "Error in Abc_NtkInsertNewLogic(): There is no PO corresponding to the PO %s.\n", Abc_ObjName(pNetH) );
00421 Abc_NtkDelete( pNtkNew );
00422 return NULL;
00423 }
00424 if ( pNetL->pCopy )
00425 continue;
00426
00427 pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) );
00428 Abc_NtkDupObj( pNtkNew, Abc_ObjFanout0(pNetL), 0 );
00429 }
00430 Abc_NtkForEachBlackbox( pNtkH, pObjH, i )
00431 {
00432 Abc_ObjForEachFanin( pObjH, pTermH, k )
00433 {
00434 char * pName;
00435 pNetH = Abc_ObjFanin0( pTermH );
00436 pName = Abc_ObjName(pNetH);
00437 pNetL = Abc_NtkFindNet( pNtkL, Abc_ObjName(pNetH) );
00438 if ( pNetL == NULL || !Abc_ObjIsPo( Abc_ObjFanout0(pNetL) ) )
00439 {
00440 printf( "There is no PO corresponding to the input %s of blackbox %s.\n", Abc_ObjName(pNetH), Abc_ObjName(pObjH) );
00441 Abc_NtkDelete( pNtkNew );
00442 return NULL;
00443 }
00444
00445 if ( pNetL->pCopy )
00446 {
00447 if ( Abc_ObjFanout0(pNetL)->pCopy == NULL )
00448 Abc_ObjFanout0(pNetL)->pCopy = pTermH->pCopy;
00449 else
00450 Abc_ObjAddFanin( pTermH->pCopy, pNetL->pCopy );
00451 continue;
00452 }
00453 pNetL->pCopy = Abc_NtkFindOrCreateNet( pNtkNew, Abc_ObjName(pNetH) );
00454 Abc_ObjFanout0(pNetL)->pCopy = pTermH->pCopy;
00455 }
00456 }
00457
00458
00459 Abc_NtkForEachObj( pNtkL, pObjL, i )
00460 if ( pObjL->pCopy == NULL && !Abc_ObjIsPo(pObjL) )
00461 Abc_NtkDupObj( pNtkNew, pObjL, Abc_ObjIsNet(pObjL) );
00462
00463
00464 Abc_NtkForEachObj( pNtkL, pObjL, i )
00465 Abc_ObjForEachFanin( pObjL, pNetL, k )
00466 if ( pObjL->pCopy )
00467 Abc_ObjAddFanin( pObjL->pCopy, pNetL->pCopy );
00468
00469
00470 pDesign = pNtkH->pDesign; pNtkH->pDesign = NULL;
00471 assert( Vec_PtrEntry( pDesign->vModules, 0 ) == pNtkH );
00472 Vec_PtrWriteEntry( pDesign->vModules, 0, pNtkNew );
00473 pNtkNew->pDesign = pDesign;
00474
00475
00476
00477
00478
00479 if ( !Abc_NtkCheck( pNtkNew ) )
00480 {
00481 fprintf( stdout, "Abc_NtkInsertNewLogic(): Network check has failed.\n" );
00482 Abc_NtkDelete( pNtkNew );
00483 return NULL;
00484 }
00485 return pNtkNew;
00486 }
00487
00491
00492