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 extern int nTotal, nGood, nEqual;
00032
00033 static Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
00034 static int Abc_NtkComputeArea( Abc_Ntk_t * pNtk, Cut_Man_t * p );
00035
00039
00051 Cut_Man_t * Abc_NtkCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
00052 {
00053 ProgressBar * pProgress;
00054 Cut_Man_t * p;
00055 Abc_Obj_t * pObj, * pNode;
00056 Vec_Ptr_t * vNodes;
00057 Vec_Int_t * vChoices;
00058 int i;
00059 int clk = clock();
00060
00061 extern void Abc_NtkBalanceAttach( Abc_Ntk_t * pNtk );
00062 extern void Abc_NtkBalanceDetach( Abc_Ntk_t * pNtk );
00063
00064 nTotal = nGood = nEqual = 0;
00065
00066 assert( Abc_NtkIsStrash(pNtk) );
00067
00068 pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
00069 p = Cut_ManStart( pParams );
00070
00071 if ( pParams->fGlobal || pParams->fLocal )
00072 {
00073 extern Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk );
00074 Cut_ManSetNodeAttrs( p, Abc_NtkGetNodeAttributes(pNtk) );
00075 }
00076
00077 if ( pParams->fDrop )
00078 Cut_ManSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
00079
00080 Abc_NtkForEachCi( pNtk, pObj, i )
00081 if ( Abc_ObjFanoutNum(pObj) > 0 )
00082 Cut_NodeSetTriv( p, pObj->Id );
00083
00084 vNodes = Abc_AigDfs( pNtk, 0, 1 );
00085 vChoices = Vec_IntAlloc( 100 );
00086 pProgress = Extra_ProgressBarStart( stdout, Vec_PtrSize(vNodes) );
00087 Vec_PtrForEachEntry( vNodes, pObj, i )
00088 {
00089
00090 if ( Abc_ObjIsCo(pObj) )
00091 {
00092 if ( pParams->fDrop )
00093 Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
00094 continue;
00095 }
00096
00097
00098
00099 Extra_ProgressBarUpdate( pProgress, i, NULL );
00100
00101 Abc_NodeGetCuts( p, pObj, pParams->fDag, pParams->fTree );
00102
00103 if ( pParams->fDrop )
00104 {
00105 Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
00106 Cut_NodeTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
00107 }
00108
00109 if ( Abc_AigNodeIsChoice(pObj) )
00110 {
00111 Vec_IntClear( vChoices );
00112 for ( pNode = pObj; pNode; pNode = pNode->pData )
00113 Vec_IntPush( vChoices, pNode->Id );
00114 Cut_NodeUnionCuts( p, vChoices );
00115 }
00116 }
00117 Extra_ProgressBarStop( pProgress );
00118 Vec_PtrFree( vNodes );
00119 Vec_IntFree( vChoices );
00120 Cut_ManPrintStats( p );
00121 PRT( "TOTAL ", clock() - clk );
00122 printf( "Area = %d.\n", Abc_NtkComputeArea( pNtk, p ) );
00123
00124
00125
00126
00127 if ( nTotal )
00128 printf( "Total cuts = %d. Good cuts = %d. Ratio = %5.2f\n", nTotal, nGood, ((double)nGood)/nTotal );
00129 return p;
00130 }
00131
00143 void Abc_NtkCutsOracle( Abc_Ntk_t * pNtk, Cut_Oracle_t * p )
00144 {
00145 Abc_Obj_t * pObj;
00146 Vec_Ptr_t * vNodes;
00147 int i, clk = clock();
00148 int fDrop = Cut_OracleReadDrop(p);
00149
00150 assert( Abc_NtkIsStrash(pNtk) );
00151
00152
00153 if ( fDrop )
00154 Cut_OracleSetFanoutCounts( p, Abc_NtkFanoutCounts(pNtk) );
00155
00156
00157 Abc_NtkForEachCi( pNtk, pObj, i )
00158 if ( Abc_ObjFanoutNum(pObj) > 0 )
00159 Cut_OracleNodeSetTriv( p, pObj->Id );
00160
00161
00162 vNodes = Abc_AigDfs( pNtk, 0, 1 );
00163 Vec_PtrForEachEntry( vNodes, pObj, i )
00164 {
00165
00166 if ( Abc_ObjIsCo(pObj) )
00167 {
00168 if ( fDrop )
00169 Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
00170 continue;
00171 }
00172
00173
00174
00175
00176 Cut_OracleComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
00177 Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj) );
00178
00179 if ( fDrop )
00180 {
00181 Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId0(pObj) );
00182 Cut_OracleTryDroppingCuts( p, Abc_ObjFaninId1(pObj) );
00183 }
00184 }
00185 Vec_PtrFree( vNodes );
00186
00187
00188 }
00189
00190
00202 Cut_Man_t * Abc_NtkSeqCuts( Abc_Ntk_t * pNtk, Cut_Params_t * pParams )
00203 {
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
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 return NULL;
00293 }
00294
00306 int Abc_NtkComputeArea( Abc_Ntk_t * pNtk, Cut_Man_t * p )
00307 {
00308 Abc_Obj_t * pObj;
00309 int Counter, i;
00310 Counter = 0;
00311 Abc_NtkForEachCo( pNtk, pObj, i )
00312 Counter += Cut_ManMappingArea_rec( p, Abc_ObjFaninId0(pObj) );
00313 return Counter;
00314 }
00315
00327 void * Abc_NodeGetCutsRecursive( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
00328 {
00329 void * pList;
00330 if ( pList = Abc_NodeReadCuts( p, pObj ) )
00331 return pList;
00332 Abc_NodeGetCutsRecursive( p, Abc_ObjFanin0(pObj), fDag, fTree );
00333 Abc_NodeGetCutsRecursive( p, Abc_ObjFanin1(pObj), fDag, fTree );
00334 return Abc_NodeGetCuts( p, pObj, fDag, fTree );
00335 }
00336
00348 void * Abc_NodeGetCuts( void * p, Abc_Obj_t * pObj, int fDag, int fTree )
00349 {
00350 Abc_Obj_t * pFanin;
00351 int fDagNode, fTriv, TreeCode = 0;
00352
00353 assert( Abc_ObjFaninNum(pObj) == 2 );
00354
00355
00356
00357 fDagNode = (Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj));
00358
00359 if ( fDagNode ) Cut_ManIncrementDagNodes( p );
00360
00361 fTriv = fDagNode || !fDag;
00362
00363 if ( fTree )
00364 {
00365 pFanin = Abc_ObjFanin0(pObj);
00366 TreeCode |= (Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin));
00367 pFanin = Abc_ObjFanin1(pObj);
00368 TreeCode |= ((Abc_ObjFanoutNum(pFanin) > 1 && !Abc_NodeIsMuxControlType(pFanin)) << 1);
00369 }
00370
00371
00372
00373 {
00374 Cut_Params_t * pParams = Cut_ManReadParams(p);
00375 if ( pParams->fLocal )
00376 {
00377 Vec_Int_t * vNodeAttrs = Cut_ManReadNodeAttrs(p);
00378 fDagNode = Vec_IntEntry( vNodeAttrs, pObj->Id );
00379 if ( fDagNode ) Cut_ManIncrementDagNodes( p );
00380
00381 fTriv = !Vec_IntEntry( vNodeAttrs, pObj->Id );
00382 TreeCode = 0;
00383 pFanin = Abc_ObjFanin0(pObj);
00384 TreeCode |= Vec_IntEntry( vNodeAttrs, pFanin->Id );
00385 pFanin = Abc_ObjFanin1(pObj);
00386 TreeCode |= (Vec_IntEntry( vNodeAttrs, pFanin->Id ) << 1);
00387 }
00388 }
00389 return Cut_NodeComputeCuts( p, pObj->Id, Abc_ObjFaninId0(pObj), Abc_ObjFaninId1(pObj),
00390 Abc_ObjFaninC0(pObj), Abc_ObjFaninC1(pObj), fTriv, TreeCode );
00391 }
00392
00404 void Abc_NodeGetCutsSeq( void * p, Abc_Obj_t * pObj, int fTriv )
00405 {
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 }
00416
00428 void * Abc_NodeReadCuts( void * p, Abc_Obj_t * pObj )
00429 {
00430 return Cut_NodeReadCutsNew( p, pObj->Id );
00431 }
00432
00444 void Abc_NodeFreeCuts( void * p, Abc_Obj_t * pObj )
00445 {
00446 Cut_NodeFreeCuts( p, pObj->Id );
00447 }
00448
00460 void Abc_NtkPrintCuts( void * p, Abc_Ntk_t * pNtk, int fSeq )
00461 {
00462 Cut_Man_t * pMan = p;
00463 Cut_Cut_t * pList;
00464 Abc_Obj_t * pObj;
00465 int i;
00466 printf( "Cuts of the network:\n" );
00467 Abc_NtkForEachObj( pNtk, pObj, i )
00468 {
00469 pList = Abc_NodeReadCuts( p, pObj );
00470 printf( "Node %s:\n", Abc_ObjName(pObj) );
00471 Cut_CutPrintList( pList, fSeq );
00472 }
00473 }
00474
00486 void Abc_NtkPrintCuts_( void * p, Abc_Ntk_t * pNtk, int fSeq )
00487 {
00488 Cut_Man_t * pMan = p;
00489 Cut_Cut_t * pList;
00490 Abc_Obj_t * pObj;
00491 pObj = Abc_NtkObj( pNtk, 2 * Abc_NtkObjNum(pNtk) / 3 );
00492 pList = Abc_NodeReadCuts( p, pObj );
00493 printf( "Node %s:\n", Abc_ObjName(pObj) );
00494 Cut_CutPrintList( pList, fSeq );
00495 }
00496
00497
00498
00499
00511 Vec_Int_t * Abc_NtkGetNodeAttributes( Abc_Ntk_t * pNtk )
00512 {
00513 Vec_Int_t * vAttrs;
00514
00515 Abc_Obj_t * pObj;
00516 int i;
00517 int nNodesTotal = 0, nMffcsTotal = 0;
00518 extern Vec_Ptr_t * Abc_NodeMffsInsideCollect( Abc_Obj_t * pNode );
00519
00520 vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
00521
00522
00523
00524 Abc_NtkForEachObj( pNtk, pObj, i )
00525 {
00526 if ( Abc_ObjIsNode(pObj) )
00527 nNodesTotal++;
00528 if ( Abc_ObjIsCo(pObj) && Abc_ObjIsNode(Abc_ObjFanin0(pObj)) )
00529 nMffcsTotal += Abc_NodeMffcSize( Abc_ObjFanin0(pObj) );
00530
00531
00532 if ( Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj) )
00533 {
00534 int nMffc = Abc_NodeMffcSize(pObj);
00535 nMffcsTotal += Abc_NodeMffcSize(pObj);
00536
00537
00538 if ( nMffc > 2 || Abc_ObjFanoutNum(pObj) > 8 )
00539 Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
00540 }
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 printf( "Total nodes = %d. Total MFFC nodes = %d.\n", nNodesTotal, nMffcsTotal );
00556 return vAttrs;
00557 }
00558
00570 int Abc_NtkSubDagSize_rec( Abc_Obj_t * pObj, Vec_Int_t * vAttrs )
00571 {
00572 if ( Abc_NodeIsTravIdCurrent(pObj) )
00573 return 0;
00574 Abc_NodeSetTravIdCurrent(pObj);
00575 if ( Vec_IntEntry( vAttrs, pObj->Id ) )
00576 return 0;
00577 if ( Abc_ObjIsCi(pObj) )
00578 return 1;
00579 assert( Abc_ObjFaninNum(pObj) == 2 );
00580 return 1 + Abc_NtkSubDagSize_rec(Abc_ObjFanin0(pObj), vAttrs) +
00581 Abc_NtkSubDagSize_rec(Abc_ObjFanin1(pObj), vAttrs);
00582 }
00583
00595 Vec_Int_t * Abc_NtkGetNodeAttributes2( Abc_Ntk_t * pNtk )
00596 {
00597 Vec_Int_t * vAttrs;
00598 Abc_Obj_t * pObj;
00599 int i, nSize;
00600 assert( Abc_NtkIsDfsOrdered(pNtk) );
00601 vAttrs = Vec_IntStart( Abc_NtkObjNumMax(pNtk) + 1 );
00602 Abc_NtkForEachObj( pNtk, pObj, i )
00603 {
00604
00605 if ( pObj->Id == 0 || !(Abc_ObjIsNode(pObj) && Abc_ObjFanoutNum(pObj) > 1 && !Abc_NodeIsMuxControlType(pObj)) )
00606 continue;
00607
00608 Abc_NtkIncrementTravId( pNtk );
00609 nSize = Abc_NtkSubDagSize_rec( pObj, vAttrs );
00610 if ( nSize > 15 )
00611 Vec_IntWriteEntry( vAttrs, pObj->Id, 1 );
00612 }
00613 return vAttrs;
00614 }
00615
00619
00620