00001
00021 #include "abc.h"
00022 #include "cut.h"
00023
00027
00028 static void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq );
00029 static void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq );
00030
00031
00032 extern int nTotal, nGood, nEqual;
00033
00034
00035
00036 Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
00037 {
00038 Vec_Int_t * vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
00039 int i;
00040 Abc_Obj_t * pObj;
00041
00042
00043
00044
00045 Abc_NtkForEachObj( pNtk, pObj, i )
00046 {
00047
00048 if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) && (rand() % 3 == 0) )
00049 Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
00050 }
00051 return vAttrs;
00052 }
00053
00057
00069 Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
00070 {
00071 ProgressBar * pProgress;
00072 Cut_Man_t * p;
00073 Abc_Obj_t * pObj, * pNode;
00074 Vec_Ptr_t * vNodes;
00075 Vec_Int_t * vChoices;
00076 int i;
00077 int clk = clock();
00078
00079 extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk );
00080 extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk );
00081
00082 nTotal = nGood = nEqual = 0;
00083
00084 assert( Abc_NtkIsStrash(pNtk) );
00085
00086 pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
00087 p = Cut_ManStart( pParams );
00088
00089 if ( pParams->fGlobal || pParams->fLocal )
00090 {
00091 extern Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
00092 Cut_ManSetNodeAttrs( p, Abc_NtkGetNodeAttributes(pNtk) );
00093 }
00094
00095 if ( pParams->fDrop )
00096 Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
00097
00098 Abc_NtkForEachCi( pNtk, pObj, i )
00099 if ( Abc_ObjFanoutNum(pObj) > 0 )
00100 Cut_NodeSetTriv( p, pObj->Id );
00101
00102 vNodes = Abc_AigDfs( pNtk, 0, 1 );
00103 vChoices = Vec_IntAlloc( 100 );
00104 pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodes) );
00105 Vec_PtrForEachEntry( vNodes, pObj, i )
00106 {
00107
00108 if ( Abc_ObjIsCo(pObj) )
00109 {
00110 if ( pParams->fDrop )
00111 Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
00112 continue;
00113 }
00114
00115
00116
00117 Extra_ProgressBarUpdate( pProgress, i, NULL );
00118
00119 Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree );
00120
00121 if ( pParams->fDrop )
00122 {
00123 Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
00124 Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
00125 }
00126
00127 if ( Abc_AigNodeIsChoice(pObj) )
00128 {
00129 Vec_IntClear( vChoices );
00130 for ( pNode = pObj; pNode; pNode = pNode->pData )
00131 Vec_IntPush( vChoices, pNode->Id );
00132 Cut_NodeUnionCuts( p, vChoices );
00133 }
00134 }
00135 Extra_ProgressBarStop( pProgress );
00136 Vec_PtrFree( vNodes );
00137 Vec_IntFree( vChoices );
00138 PRT( "Total", clock() - clk );
00139
00140
00141
00142
00143 if ( nTotal )
00144 printf( "Total cuts = %d. Good cuts = %d. Ratio = %5.2f\n", nTotal, nGood, ((double)nGood)/nTotal );
00145 return p;
00146 }
00147
00159 void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p )
00160 {
00161 Abc_Obj_t * pObj;
00162 Vec_Ptr_t * vNodes;
00163 int i, clk = clock();
00164 int fDrop = Cut_OracleReadDrop(p);
00165
00166 assert( Abc_NtkIsStrash(pNtk) );
00167
00168
00169 if ( fDrop )
00170 Cut_OracleSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
00171
00172
00173 Abc_NtkForEachCi( pNtk, pObj, i )
00174 if ( Abc_ObjFanoutNum(pObj) > 0 )
00175 Cut_OracleNodeSetTriv( p, pObj->Id );
00176
00177
00178 vNodes = Abc_AigDfs( pNtk, 0, 1 );
00179 Vec_PtrForEachEntry( vNodes, pObj, i )
00180 {
00181
00182 if ( Abc_ObjIsCo(pObj) )
00183 {
00184 if ( fDrop )
00185 Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
00186 continue;
00187 }
00188
00189
00190
00191
00192 Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
00193 Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
00194
00195 if ( fDrop )
00196 {
00197 Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
00198 Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
00199 }
00200 }
00201 Vec_PtrFree( vNodes );
00202
00203
00204 }
00205
00206
00218 Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
00219 {
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 }
00308
00320 void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
00321 {
00322 void * pList;
00323 if ( pList = Abc_NodeReadCuts( p, pObj ) )
00324 return pList;
00325 Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fDag, fTree );
00326 Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fDag, fTree );
00327 return Abc_NodeGetCuts( p, pObj, fDag, fTree );
00328 }
00329
00341 void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
00342 {
00343 Abc_Obj_t * pFanin;
00344 int fDagNode, fTriv, TreeCode = 0;
00345
00346 assert( Abc_ObjFaninNum(pObj) == 2 );
00347
00348
00349
00350 fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj));
00351
00352 if ( fDagNode ) Cut_ManIncrementDagNodes( p );
00353
00354 fTriv = fDagNode || !fDag;
00355
00356 if ( fTree )
00357 {
00358 pFanin = Abc_ObjFanin0(pObj);
00359 TreeCode |= (Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin));
00360 pFanin = Abc_ObjFanin1(pObj);
00361 TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1);
00362 }
00363
00364
00365
00366 {
00367 Cut_Params_t * pParams = Cut_ManReadParams(p);
00368 if ( pParams->fLocal )
00369 {
00370 Vec_Int_t * vNodeAttrs = Cut_ManReadNodeAttrs(p);
00371 fDagNode = Vec_IntEntry( vNodeAttrs, pObj->Id );
00372 if ( fDagNode ) Cut_ManIncrementDagNodes( p );
00373
00374 fTriv = !Vec_IntEntry( vNodeAttrs, pObj->Id );
00375 TreeCode = 0;
00376 pFanin = Abc_ObjFanin0(pObj);
00377 TreeCode |= Vec_IntEntry( vNodeAttrs, pFanin->Id );
00378 pFanin = Abc_ObjFanin1(pObj);
00379 TreeCode |= (Vec_IntEntry( vNodeAttrs, pFanin->Id ) << 1);
00380 }
00381 }
00382 return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
00383 Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv, TreeCode );
00384 }
00385
00397 void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv )
00398 {
00399 int CutSetNum;
00400 assert( Abc_NtkIsSeq(pObj->pNtk) );
00401 assert( Abc_ObjFaninNum(pObj) == 2 );
00402 fTriv = pObj->fMarkC ? 0 : fTriv;
00403 CutSetNum = pObj->fMarkC ? (int)pObj->pCopy : -1;
00404 Cut_NodeComputeCutsSeq( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
00405 Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), Seq_ObjFaninL0(pObj), Seq_ObjFaninL1(pObj), fTriv, CutSetNum );
00406 }
00407
00419 void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj )
00420 {
00421 return Cut_NodeReadCutsNew( p, pObj->Id );
00422 }
00423
00435 void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj )
00436 {
00437 Cut_NodeFreeCuts( p, pObj->Id );
00438 }
00439
00451 void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq )
00452 {
00453 Cut_Man_t * pMan = p;
00454 Cut_Cut_t * pList;
00455 Abc_Obj_t * pObj;
00456 int i;
00457 printf( "Cuts of the network:\n" );
00458 Abc_NtkForEachObj( pNtk, pObj, i )
00459 {
00460 pList = Abc_NodeReadCuts( p, pObj );
00461 printf( "Node %s:\n", Abc_ObjName(pObj) );
00462 Cut_CutPrintList( pList, fSeq );
00463 }
00464 }
00465
00477 void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq )
00478 {
00479 Cut_Man_t * pMan = p;
00480 Cut_Cut_t * pList;
00481 Abc_Obj_t * pObj;
00482 pObj = Abc_NtkObj( pNtk, 2 * Abc_NtkObjNum(pNtk) / 3 );
00483 pList = Abc_NodeReadCuts( p, pObj );
00484 printf( "Node %s:\n", Abc_ObjName(pObj) );
00485 Cut_CutPrintList( pList, fSeq );
00486 }
00487
00491
00492