00001
00021 #include "abc.h"
00022 #include "dec.h"
00023
00027
00028 typedef struct Abc_ManRef_t_ Abc_ManRef_t;
00029 struct Abc_ManRef_t_
00030 {
00031
00032 int nNodeSizeMax;
00033 int nConeSizeMax;
00034 int fVerbose;
00035
00036 DdManager * dd;
00037 Vec_Str_t * vCube;
00038 Vec_Int_t * vForm;
00039 Vec_Ptr_t * vVisited;
00040 Vec_Ptr_t * vLeaves;
00041
00042 int nLastGain;
00043 int nNodesConsidered;
00044 int nNodesRefactored;
00045 int nNodesGained;
00046 int nNodesBeg;
00047 int nNodesEnd;
00048
00049 int timeCut;
00050 int timeBdd;
00051 int timeDcs;
00052 int timeSop;
00053 int timeFact;
00054 int timeEval;
00055 int timeRes;
00056 int timeNtk;
00057 int timeTotal;
00058 };
00059
00060 static void Abc_NtkManRefPrintStats( Abc_ManRef_t * p );
00061 static Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUseDcs, bool fVerbose );
00062 static void Abc_NtkManRefStop( Abc_ManRef_t * p );
00063 static Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUpdateLevel, bool fUseZeros, bool fUseDcs, bool fVerbose );
00064
00068
00085 int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, bool fUpdateLevel, bool fUseZeros, bool fUseDcs, bool fVerbose )
00086 {
00087 ProgressBar * pProgress;
00088 Abc_ManRef_t * pManRef;
00089 Abc_ManCut_t * pManCut;
00090 Dec_Graph_t * pFForm;
00091 Vec_Ptr_t * vFanins;
00092 Abc_Obj_t * pNode;
00093 int clk, clkStart = clock();
00094 int i, nNodes;
00095
00096 assert( Abc_NtkIsStrash(pNtk) );
00097
00098 Abc_AigCleanup(pNtk->pManFunc);
00099
00100 pManCut = Abc_NtkManCutStart( nNodeSizeMax, nConeSizeMax, 2, 1000 );
00101 pManRef = Abc_NtkManRefStart( nNodeSizeMax, nConeSizeMax, fUseDcs, fVerbose );
00102 pManRef->vLeaves = Abc_NtkManCutReadCutLarge( pManCut );
00103
00104 if ( fUpdateLevel )
00105 Abc_NtkStartReverseLevels( pNtk, 0 );
00106
00107
00108 pManRef->nNodesBeg = Abc_NtkNodeNum(pNtk);
00109 nNodes = Abc_NtkObjNumMax(pNtk);
00110 pProgress = Extra_ProgressBarStart( stdout, nNodes );
00111 Abc_NtkForEachNode( pNtk, pNode, i )
00112 {
00113 Extra_ProgressBarUpdate( pProgress, i, NULL );
00114
00115
00116
00117
00118 if ( Abc_NodeIsPersistant(pNode) )
00119 continue;
00120
00121 if ( Abc_ObjFanoutNum(pNode) > 1000 )
00122 continue;
00123
00124 if ( i >= nNodes )
00125 break;
00126
00127 clk = clock();
00128 vFanins = Abc_NodeFindCut( pManCut, pNode, fUseDcs );
00129 pManRef->timeCut += clock() - clk;
00130
00131 clk = clock();
00132 pFForm = Abc_NodeRefactor( pManRef, pNode, vFanins, fUpdateLevel, fUseZeros, fUseDcs, fVerbose );
00133 pManRef->timeRes += clock() - clk;
00134 if ( pFForm == NULL )
00135 continue;
00136
00137 clk = clock();
00138 Dec_GraphUpdateNetwork( pNode, pFForm, fUpdateLevel, pManRef->nLastGain );
00139 pManRef->timeNtk += clock() - clk;
00140 Dec_GraphFree( pFForm );
00141
00142
00143
00144
00145 }
00146 Extra_ProgressBarStop( pProgress );
00147 pManRef->timeTotal = clock() - clkStart;
00148 pManRef->nNodesEnd = Abc_NtkNodeNum(pNtk);
00149
00150
00151 if ( fVerbose )
00152 Abc_NtkManRefPrintStats( pManRef );
00153
00154 Abc_NtkManCutStop( pManCut );
00155 Abc_NtkManRefStop( pManRef );
00156
00157 Abc_NtkReassignIds( pNtk );
00158
00159
00160 if ( fUpdateLevel )
00161 Abc_NtkStopReverseLevels( pNtk );
00162 else
00163 Abc_NtkLevel( pNtk );
00164
00165 if ( !Abc_NtkCheck( pNtk ) )
00166 {
00167 printf( "Abc_NtkRefactor: The network check has failed.\n" );
00168 return 0;
00169 }
00170 return 1;
00171 }
00172
00184 Dec_Graph_t * Abc_NodeRefactor( Abc_ManRef_t * p, Abc_Obj_t * pNode, Vec_Ptr_t * vFanins, bool fUpdateLevel, bool fUseZeros, bool fUseDcs, bool fVerbose )
00185 {
00186 int fVeryVerbose = 0;
00187 Abc_Obj_t * pFanin;
00188 Dec_Graph_t * pFForm;
00189 DdNode * bNodeFunc;
00190 int nNodesSaved, nNodesAdded, i, clk;
00191 char * pSop;
00192 int Required;
00193
00194 Required = fUpdateLevel? Abc_ObjRequiredLevel(pNode) : ABC_INFINITY;
00195
00196 p->nNodesConsidered++;
00197
00198
00199 clk = clock();
00200 bNodeFunc = Abc_NodeConeBdd( p->dd, p->dd->vars, pNode, vFanins, p->vVisited ); Cudd_Ref( bNodeFunc );
00201 p->timeBdd += clock() - clk;
00202
00203
00204 if ( fUseDcs )
00205 {
00206 DdNode * bNodeDc, * bNodeOn, * bNodeOnDc;
00207 int nMints, nMintsDc;
00208 clk = clock();
00209
00210 bNodeDc = Abc_NodeConeDcs( p->dd, p->dd->vars + vFanins->nSize, p->dd->vars, p->vLeaves, vFanins, p->vVisited ); Cudd_Ref( bNodeDc );
00211 nMints = (1 << vFanins->nSize);
00212 nMintsDc = (int)Cudd_CountMinterm( p->dd, bNodeDc, vFanins->nSize );
00213
00214
00215 bNodeOn = Cudd_bddAnd( p->dd, bNodeFunc, Cudd_Not(bNodeDc) ); Cudd_Ref( bNodeOn );
00216 bNodeOnDc = Cudd_bddOr ( p->dd, bNodeFunc, bNodeDc ); Cudd_Ref( bNodeOnDc );
00217 Cudd_RecursiveDeref( p->dd, bNodeFunc );
00218 Cudd_RecursiveDeref( p->dd, bNodeDc );
00219
00220 bNodeFunc = Cudd_bddIsop( p->dd, bNodeOn, bNodeOnDc ); Cudd_Ref( bNodeFunc );
00221 Cudd_RecursiveDeref( p->dd, bNodeOn );
00222 Cudd_RecursiveDeref( p->dd, bNodeOnDc );
00223 p->timeDcs += clock() - clk;
00224 }
00225
00226
00227 if ( Cudd_IsConstant(bNodeFunc) )
00228 {
00229 p->nLastGain = Abc_NodeMffcSize( pNode );
00230 p->nNodesGained += p->nLastGain;
00231 p->nNodesRefactored++;
00232 Cudd_RecursiveDeref( p->dd, bNodeFunc );
00233 if ( Cudd_IsComplement(bNodeFunc) )
00234 return Dec_GraphCreateConst0();
00235 return Dec_GraphCreateConst1();
00236 }
00237
00238
00239 clk = clock();
00240 pSop = Abc_ConvertBddToSop( NULL, p->dd, bNodeFunc, bNodeFunc, vFanins->nSize, 0, p->vCube, -1 );
00241 p->timeSop += clock() - clk;
00242
00243
00244 clk = clock();
00245 pFForm = Dec_Factor( pSop );
00246 free( pSop );
00247 p->timeFact += clock() - clk;
00248
00249
00250
00251 Vec_PtrForEachEntry( vFanins, pFanin, i )
00252 pFanin->vFanouts.nSize++;
00253
00254 Abc_NtkIncrementTravId( pNode->pNtk );
00255 nNodesSaved = Abc_NodeMffcLabelAig( pNode );
00256
00257 Vec_PtrForEachEntry( vFanins, pFanin, i )
00258 {
00259 pFanin->vFanouts.nSize--;
00260 Dec_GraphNode(pFForm, i)->pFunc = pFanin;
00261 }
00262
00263
00264 clk = clock();
00265 nNodesAdded = Dec_GraphToNetworkCount( pNode, pFForm, nNodesSaved, Required );
00266 p->timeEval += clock() - clk;
00267
00268 if ( nNodesAdded == -1 || nNodesAdded == nNodesSaved && !fUseZeros )
00269 {
00270 Cudd_RecursiveDeref( p->dd, bNodeFunc );
00271 Dec_GraphFree( pFForm );
00272 return NULL;
00273 }
00274
00275
00276 p->nLastGain = nNodesSaved - nNodesAdded;
00277 p->nNodesGained += p->nLastGain;
00278 p->nNodesRefactored++;
00279
00280
00281 if ( fVeryVerbose )
00282 {
00283 printf( "Node %6s : ", Abc_ObjName(pNode) );
00284 printf( "Cone = %2d. ", vFanins->nSize );
00285 printf( "BDD = %2d. ", Cudd_DagSize(bNodeFunc) );
00286 printf( "FF = %2d. ", 1 + Dec_GraphNodeNum(pFForm) );
00287 printf( "MFFC = %2d. ", nNodesSaved );
00288 printf( "Add = %2d. ", nNodesAdded );
00289 printf( "GAIN = %2d. ", p->nLastGain );
00290 printf( "\n" );
00291 }
00292 Cudd_RecursiveDeref( p->dd, bNodeFunc );
00293 return pFForm;
00294 }
00295
00296
00308 Abc_ManRef_t * Abc_NtkManRefStart( int nNodeSizeMax, int nConeSizeMax, bool fUseDcs, bool fVerbose )
00309 {
00310 Abc_ManRef_t * p;
00311 p = ALLOC( Abc_ManRef_t, 1 );
00312 memset( p, 0, sizeof(Abc_ManRef_t) );
00313 p->vCube = Vec_StrAlloc( 100 );
00314 p->vVisited = Vec_PtrAlloc( 100 );
00315 p->nNodeSizeMax = nNodeSizeMax;
00316 p->nConeSizeMax = nConeSizeMax;
00317 p->fVerbose = fVerbose;
00318
00319 if ( fUseDcs )
00320 p->dd = Cudd_Init( p->nNodeSizeMax + p->nConeSizeMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
00321 else
00322 p->dd = Cudd_Init( p->nNodeSizeMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
00323 Cudd_zddVarsFromBddVars( p->dd, 2 );
00324 return p;
00325 }
00326
00338 void Abc_NtkManRefStop( Abc_ManRef_t * p )
00339 {
00340 Extra_StopManager( p->dd );
00341 Vec_PtrFree( p->vVisited );
00342 Vec_StrFree( p->vCube );
00343 free( p );
00344 }
00345
00357 void Abc_NtkManRefPrintStats( Abc_ManRef_t * p )
00358 {
00359 printf( "Refactoring statistics:\n" );
00360 printf( "Nodes considered = %8d.\n", p->nNodesConsidered );
00361 printf( "Nodes refactored = %8d.\n", p->nNodesRefactored );
00362 printf( "Gain = %8d. (%6.2f %%).\n", p->nNodesBeg-p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/p->nNodesBeg );
00363 PRT( "Cuts ", p->timeCut );
00364 PRT( "Resynthesis", p->timeRes );
00365 PRT( " BDD ", p->timeBdd );
00366 PRT( " DCs ", p->timeDcs );
00367 PRT( " SOP ", p->timeSop );
00368 PRT( " FF ", p->timeFact );
00369 PRT( " Eval ", p->timeEval );
00370 PRT( "AIG update ", p->timeNtk );
00371 PRT( "TOTAL ", p->timeTotal );
00372 }
00373
00374
00378
00379