00001
00021 #include "abc.h"
00022 #include "extra.h"
00023 #include "dec.h"
00024
00028
00029 static void Abc_NtkStrashPerform( Abc_Ntk_t * pNtk, Abc_Ntk_t * pNtkNew, int fAllNodes, int fRecord );
00030
00034
00047 Abc_Ntk_t * Abc_NtkRestrash( Abc_Ntk_t * pNtk, bool fCleanup )
00048 {
00049 extern int timeRetime;
00050 Abc_Ntk_t * pNtkAig;
00051 Abc_Obj_t * pObj;
00052 int i, nNodes;
00053 assert( Abc_NtkIsStrash(pNtk) );
00054
00055
00056 if ( Abc_NtkGetChoiceNum( pNtk ) )
00057 printf( "Warning: The choice nodes in the original AIG are removed by strashing.\n" );
00058
00059 pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
00060
00061 Abc_NtkForEachNode( pNtk, pObj, i )
00062 pObj->pCopy = Abc_AigAnd( pNtkAig->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
00063
00064 Abc_NtkFinalize( pNtk, pNtkAig );
00065
00066
00067
00068
00069 if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
00070 printf( "Abc_NtkRestrash(): AIG cleanup removed %d nodes (this is a bug).\n", nNodes );
00071
00072 if ( pNtk->pExdc )
00073 pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
00074
00075 if ( !Abc_NtkCheck( pNtkAig ) )
00076 {
00077 printf( "Abc_NtkStrash: The network check has failed.\n" );
00078 Abc_NtkDelete( pNtkAig );
00079 return NULL;
00080 }
00081
00082
00083
00084 return pNtkAig;
00085
00086 }
00087
00100 Abc_Ntk_t * Abc_NtkRestrashZero( Abc_Ntk_t * pNtk, bool fCleanup )
00101 {
00102 extern int timeRetime;
00103 Abc_Ntk_t * pNtkAig;
00104 Abc_Obj_t * pObj;
00105 int i, nNodes;
00106 assert( Abc_NtkIsStrash(pNtk) );
00107
00108
00109 if ( Abc_NtkGetChoiceNum( pNtk ) )
00110 printf( "Warning: The choice nodes in the original AIG are removed by strashing.\n" );
00111
00112 pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
00113
00114 Abc_NtkForEachLatch( pNtk, pObj, i )
00115 if ( Abc_LatchIsInit1(pObj) )
00116 Abc_ObjFanout0(pObj)->pCopy = Abc_ObjNot(Abc_ObjFanout0(pObj)->pCopy);
00117
00118 Abc_NtkForEachNode( pNtk, pObj, i )
00119 pObj->pCopy = Abc_AigAnd( pNtkAig->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
00120
00121 Abc_NtkFinalize( pNtk, pNtkAig );
00122
00123 Abc_NtkForEachLatch( pNtkAig, pObj, i )
00124 if ( Abc_LatchIsInit1(pObj) )
00125 Abc_ObjXorFaninC( Abc_ObjFanin0(pObj), 0 );
00126
00127 Abc_NtkForEachLatch( pNtkAig, pObj, i )
00128 Abc_LatchSetInit0( pObj );
00129
00130
00131
00132
00133
00134 if ( fCleanup && (nNodes = Abc_AigCleanup(pNtkAig->pManFunc)) )
00135 printf( "Abc_NtkRestrash(): AIG cleanup removed %d nodes (this is a bug).\n", nNodes );
00136
00137 if ( pNtk->pExdc )
00138 pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
00139
00140 if ( !Abc_NtkCheck( pNtkAig ) )
00141 {
00142 printf( "Abc_NtkStrash: The network check has failed.\n" );
00143 Abc_NtkDelete( pNtkAig );
00144 return NULL;
00145 }
00146
00147
00148
00149 return pNtkAig;
00150
00151 }
00152
00164 Abc_Ntk_t * Abc_NtkStrash( Abc_Ntk_t * pNtk, int fAllNodes, int fCleanup, int fRecord )
00165 {
00166 Abc_Ntk_t * pNtkAig;
00167 int nNodes;
00168 assert( Abc_NtkIsLogic(pNtk) || Abc_NtkIsStrash(pNtk) );
00169
00170 if ( Abc_NtkIsStrash(pNtk) )
00171 return Abc_NtkRestrash( pNtk, fCleanup );
00172
00173 if ( !Abc_NtkToAig(pNtk) )
00174 {
00175 printf( "Converting to AIGs has failed.\n" );
00176 return NULL;
00177 }
00178
00179
00180 pNtkAig = Abc_NtkStartFrom( pNtk, ABC_NTK_STRASH, ABC_FUNC_AIG );
00181 Abc_NtkStrashPerform( pNtk, pNtkAig, fAllNodes, fRecord );
00182 Abc_NtkFinalize( pNtk, pNtkAig );
00183
00184
00185
00186
00187 nNodes = fCleanup? Abc_AigCleanup(pNtkAig->pManFunc) : 0;
00188
00189
00190
00191 if ( pNtk->pExdc )
00192 pNtkAig->pExdc = Abc_NtkDup( pNtk->pExdc );
00193
00194 if ( !Abc_NtkCheck( pNtkAig ) )
00195 {
00196 printf( "Abc_NtkStrash: The network check has failed.\n" );
00197 Abc_NtkDelete( pNtkAig );
00198 return NULL;
00199 }
00200 return pNtkAig;
00201 }
00202
00216 int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos )
00217 {
00218 Abc_Obj_t * pObj;
00219 char * pName;
00220 int i, nNewCis;
00221
00222 assert( Abc_NtkIsStrash(pNtk1) );
00223 assert( Abc_NtkIsLogic(pNtk2) || Abc_NtkIsStrash(pNtk2) );
00224 if ( Abc_NtkIsLogic(pNtk2) && !Abc_NtkToAig(pNtk2) )
00225 {
00226 printf( "Converting to AIGs has failed.\n" );
00227 return 0;
00228 }
00229
00230
00231 if ( !Abc_NtkCompareSignals( pNtk1, pNtk2, 1, 1 ) )
00232 printf( "Abc_NtkAppend(): The union of the network PIs is computed (warning).\n" );
00233
00234 nNewCis = 0;
00235 Abc_NtkCleanCopy( pNtk2 );
00236 if ( Abc_NtkIsStrash(pNtk2) )
00237 Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtk1);
00238 Abc_NtkForEachCi( pNtk2, pObj, i )
00239 {
00240 pName = Abc_ObjName(pObj);
00241 pObj->pCopy = Abc_NtkFindCi(pNtk1, Abc_ObjName(pObj));
00242 if ( pObj->pCopy == NULL )
00243 {
00244 pObj->pCopy = Abc_NtkDupObj(pNtk1, pObj, 1);
00245 nNewCis++;
00246 }
00247 }
00248 if ( nNewCis )
00249 printf( "Warning: Procedure Abc_NtkAppend() added %d new CIs.\n", nNewCis );
00250
00251 if ( Abc_NtkIsLogic(pNtk2) )
00252 Abc_NtkStrashPerform( pNtk2, pNtk1, 1, 0 );
00253 else
00254 Abc_NtkForEachNode( pNtk2, pObj, i )
00255 pObj->pCopy = Abc_AigAnd( pNtk1->pManFunc, Abc_ObjChild0Copy(pObj), Abc_ObjChild1Copy(pObj) );
00256
00257 if ( fAddPos )
00258 {
00259 Abc_NtkForEachPo( pNtk2, pObj, i )
00260 {
00261 Abc_NtkDupObj( pNtk1, pObj, 0 );
00262 Abc_ObjAddFanin( pObj->pCopy, Abc_ObjChild0Copy(pObj) );
00263 Abc_ObjAssignName( pObj->pCopy, Abc_ObjName(pObj->pCopy), NULL );
00264 }
00265 }
00266 else
00267 {
00268 Abc_Obj_t * pObjOld, * pDriverOld, * pDriverNew;
00269 int fCompl, iNodeId;
00270
00271 Abc_NtkForEachCo( pNtk2, pObj, i )
00272 {
00273 iNodeId = Nm_ManFindIdByNameTwoTypes( pNtk1->pManName, Abc_ObjName(pObj), ABC_OBJ_PO, ABC_OBJ_BI );
00274 assert( iNodeId >= 0 );
00275 pObjOld = Abc_NtkObj( pNtk1, iNodeId );
00276
00277 pDriverOld = Abc_ObjChild0( pObjOld );
00278 pDriverNew = Abc_ObjChild0Copy( pObj );
00279 pDriverNew = Abc_AigOr( pNtk1->pManFunc, pDriverOld, pDriverNew );
00280 if ( Abc_ObjRegular(pDriverOld) == Abc_ObjRegular(pDriverNew) )
00281 continue;
00282
00283 fCompl = Abc_ObjRegular(pDriverOld)->fPhase ^ Abc_ObjRegular(pDriverNew)->fPhase;
00284 Abc_ObjPatchFanin( pObjOld, Abc_ObjRegular(pDriverOld), Abc_ObjNotCond(Abc_ObjRegular(pDriverNew), fCompl) );
00285 }
00286 }
00287
00288 if ( !Abc_NtkCheck( pNtk1 ) )
00289 {
00290 printf( "Abc_NtkAppend: The network check has failed.\n" );
00291 return 0;
00292 }
00293 return 1;
00294 }
00295
00307 void Abc_NtkStrashPerform( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew, int fAllNodes, int fRecord )
00308 {
00309 ProgressBar * pProgress;
00310 Vec_Ptr_t * vNodes;
00311 Abc_Obj_t * pNodeOld;
00312 int i, clk = clock();
00313 assert( Abc_NtkIsLogic(pNtkOld) );
00314 assert( Abc_NtkIsStrash(pNtkNew) );
00315
00316 vNodes = Abc_NtkDfsIter( pNtkOld, fAllNodes );
00317
00318
00319 pProgress = Extra_ProgressBarStart( stdout, vNodes->nSize );
00320 Vec_PtrForEachEntry( vNodes, pNodeOld, i )
00321 {
00322 Extra_ProgressBarUpdate( pProgress, i, NULL );
00323 pNodeOld->pCopy = Abc_NodeStrash( pNtkNew, pNodeOld, fRecord );
00324 }
00325 Extra_ProgressBarStop( pProgress );
00326 Vec_PtrFree( vNodes );
00327 }
00328
00340 void Abc_NodeStrash_rec( Abc_Aig_t * pMan, Hop_Obj_t * pObj )
00341 {
00342 assert( !Hop_IsComplement(pObj) );
00343 if ( !Hop_ObjIsNode(pObj) || Hop_ObjIsMarkA(pObj) )
00344 return;
00345 Abc_NodeStrash_rec( pMan, Hop_ObjFanin0(pObj) );
00346 Abc_NodeStrash_rec( pMan, Hop_ObjFanin1(pObj) );
00347 pObj->pData = Abc_AigAnd( pMan, (Abc_Obj_t *)Hop_ObjChild0Copy(pObj), (Abc_Obj_t *)Hop_ObjChild1Copy(pObj) );
00348 assert( !Hop_ObjIsMarkA(pObj) );
00349 Hop_ObjSetMarkA( pObj );
00350 }
00351
00363 Abc_Obj_t * Abc_NodeStrash( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNodeOld, int fRecord )
00364 {
00365 Hop_Man_t * pMan;
00366 Hop_Obj_t * pRoot;
00367 Abc_Obj_t * pFanin;
00368 int i;
00369 assert( Abc_ObjIsNode(pNodeOld) );
00370 assert( Abc_NtkHasAig(pNodeOld->pNtk) && !Abc_NtkIsStrash(pNodeOld->pNtk) );
00371
00372 pMan = pNodeOld->pNtk->pManFunc;
00373 pRoot = pNodeOld->pData;
00374
00375 if ( Abc_NodeIsConst(pNodeOld) || Hop_Regular(pRoot) == Hop_ManConst1(pMan) )
00376 return Abc_ObjNotCond( Abc_AigConst1(pNtkNew), Hop_IsComplement(pRoot) );
00377
00378 if ( fRecord && Abc_NtkRecIsRunning() && Abc_ObjFaninNum(pNodeOld) > 2 && Abc_ObjFaninNum(pNodeOld) <= Abc_NtkRecVarNum() )
00379 {
00380 extern Vec_Int_t * Abc_NtkRecMemory();
00381 extern int Abc_NtkRecStrashNode( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pObj, unsigned * pTruth, int nVars );
00382 int nVars = Abc_NtkRecVarNum();
00383 Vec_Int_t * vMemory = Abc_NtkRecMemory();
00384 unsigned * pTruth = Abc_ConvertAigToTruth( pMan, Hop_Regular(pRoot), nVars, vMemory, 0 );
00385 assert( Extra_TruthSupportSize(pTruth, nVars) == Abc_ObjFaninNum(pNodeOld) );
00386 if ( Hop_IsComplement(pRoot) )
00387 Extra_TruthNot( pTruth, pTruth, nVars );
00388 if ( Abc_NtkRecStrashNode( pNtkNew, pNodeOld, pTruth, nVars ) )
00389 return pNodeOld->pCopy;
00390 }
00391
00392 Abc_ObjForEachFanin( pNodeOld, pFanin, i )
00393 Hop_IthVar(pMan, i)->pData = pFanin->pCopy;
00394
00395 Abc_NodeStrash_rec( pNtkNew->pManFunc, Hop_Regular(pRoot) );
00396 Hop_ConeUnmark_rec( Hop_Regular(pRoot) );
00397
00398 return Abc_ObjNotCond( Hop_Regular(pRoot)->pData, Hop_IsComplement(pRoot) );
00399 }
00400
00401
00402
00403
00404
00405
00406
00418 Abc_Obj_t * Abc_NtkTopmost_rec( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int LevelCut )
00419 {
00420 assert( !Abc_ObjIsComplement(pNode) );
00421 if ( pNode->pCopy )
00422 return pNode->pCopy;
00423 if ( pNode->Level <= (unsigned)LevelCut )
00424 return pNode->pCopy = Abc_NtkCreatePi( pNtkNew );
00425 Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(pNode), LevelCut );
00426 Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin1(pNode), LevelCut );
00427 return pNode->pCopy = Abc_AigAnd( pNtkNew->pManFunc, Abc_ObjChild0Copy(pNode), Abc_ObjChild1Copy(pNode) );
00428 }
00429
00441 Abc_Ntk_t * Abc_NtkTopmost( Abc_Ntk_t * pNtk, int nLevels )
00442 {
00443 Abc_Ntk_t * pNtkNew;
00444 Abc_Obj_t * pObjNew, * pPoNew;
00445 int LevelCut;
00446 assert( Abc_NtkIsStrash(pNtk) );
00447 assert( Abc_NtkCoNum(pNtk) == 1 );
00448
00449 LevelCut = ABC_MAX( 0, Abc_AigLevel(pNtk) - nLevels );
00450
00451 pNtkNew = Abc_NtkAlloc( ABC_NTK_STRASH, ABC_FUNC_AIG, 1 );
00452 pNtkNew->pName = Extra_UtilStrsav(pNtk->pName);
00453 Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkNew);
00454
00455 Abc_NtkCleanCopy( pNtk );
00456 pObjNew = Abc_NtkTopmost_rec( pNtkNew, Abc_ObjFanin0(Abc_NtkPo(pNtk, 0)), LevelCut );
00457 pObjNew = Abc_ObjNotCond( pObjNew, Abc_ObjFaninC0(Abc_NtkPo(pNtk, 0)) );
00458
00459 pPoNew = Abc_NtkCreatePo(pNtkNew);
00460 Abc_ObjAddFanin( pPoNew, pObjNew );
00461 Abc_NtkAddDummyPiNames( pNtkNew );
00462 Abc_ObjAssignName( pPoNew, Abc_ObjName(Abc_NtkPo(pNtk, 0)), NULL );
00463
00464 if ( !Abc_NtkCheck( pNtkNew ) )
00465 {
00466 printf( "Abc_NtkTopmost: The network check has failed.\n" );
00467 Abc_NtkDelete( pNtkNew );
00468 return NULL;
00469 }
00470 return pNtkNew;
00471 }
00472
00473
00477
00478