00001
00021 #include "abc.h"
00022
00026
00027 static int Abc_NtkCountFaninsTotal( Abc_Ntk_t * pNtk );
00028 static Abc_Ntk_t * Abc_NtkAutoDebugModify( Abc_Ntk_t * pNtk, int ObjNum, int fConst1 );
00029
00030 extern void Io_WriteBlifLogic( Abc_Ntk_t * pNtk, char * FileName, int fWriteLatches );
00031
00035
00048 void Abc_NtkAutoDebug( Abc_Ntk_t * pNtk, int (*pFuncError) (Abc_Ntk_t *) )
00049 {
00050 Abc_Ntk_t * pNtkMod;
00051 char * pFileName = "bug_found.blif";
00052 int i, nSteps, nIter, ModNum, RandNum = 1, clk, clkTotal = clock();
00053 assert( Abc_NtkIsLogic(pNtk) );
00054 srand( 0x123123 );
00055
00056 pNtk = Abc_NtkDup(pNtk);
00057 if ( !(*pFuncError)( pNtk ) )
00058 {
00059 printf( "The original network does not cause the bug. Quitting.\n" );
00060 Abc_NtkDelete( pNtk );
00061 return;
00062 }
00063
00064 for ( nIter = 0; ; nIter++ )
00065 {
00066 clk = clock();
00067
00068 nSteps = 2 * Abc_NtkCountFaninsTotal(pNtk);
00069
00070 RandNum ^= rand();
00071 for ( i = 0; i < nSteps; i++ )
00072 {
00073
00074 ModNum = (i + RandNum) % nSteps;
00075
00076 pNtkMod = Abc_NtkAutoDebugModify( pNtk, ModNum/2, ModNum%2 );
00077
00078 Io_WriteBlifLogic( pNtk, "bug_temp.blif", 1 );
00079
00080 if ( (*pFuncError)( pNtkMod ) )
00081 {
00082 Abc_NtkDelete( pNtk );
00083 pNtk = pNtkMod;
00084 break;
00085 }
00086 else
00087 Abc_NtkDelete( pNtkMod );
00088 }
00089 printf( "Iter %6d : Latches = %6d. Nodes = %6d. Steps = %6d. Error step = %3d. ",
00090 nIter, Abc_NtkLatchNum(pNtk), Abc_NtkNodeNum(pNtk), nSteps, i );
00091 PRT( "Time", clock() - clk );
00092 if ( i == nSteps )
00093 break;
00094 }
00095
00096 Io_WriteBlifLogic( pNtk, pFileName, 1 );
00097 printf( "Final network written into file \"%s\". ", pFileName );
00098 PRT( "Total time", clock() - clkTotal );
00099 Abc_NtkDelete( pNtk );
00100 }
00101
00113 int Abc_NtkCountFaninsTotal( Abc_Ntk_t * pNtk )
00114 {
00115 Abc_Obj_t * pObj, * pFanin;
00116 int i, k, Counter = 0;
00117 Abc_NtkForEachObj( pNtk, pObj, i )
00118 Abc_ObjForEachFanin( pObj, pFanin, k )
00119 {
00120 if ( !Abc_ObjIsNode(pObj) && !Abc_ObjIsPo(pObj) )
00121 continue;
00122 if ( Abc_ObjIsPo(pObj) && Abc_NtkPoNum(pNtk) == 1 )
00123 continue;
00124 if ( Abc_ObjIsNode(pObj) && Abc_NodeIsConst(pFanin) )
00125 continue;
00126 Counter++;
00127 }
00128 return Counter;
00129 }
00130
00142 int Abc_NtkFindGivenFanin( Abc_Ntk_t * pNtk, int Step, Abc_Obj_t ** ppObj, Abc_Obj_t ** ppFanin )
00143 {
00144 Abc_Obj_t * pObj, * pFanin;
00145 int i, k, Counter = 0;
00146 Abc_NtkForEachObj( pNtk, pObj, i )
00147 Abc_ObjForEachFanin( pObj, pFanin, k )
00148 {
00149 if ( !Abc_ObjIsNode(pObj) && !Abc_ObjIsPo(pObj) )
00150 continue;
00151 if ( Abc_ObjIsPo(pObj) && Abc_NtkPoNum(pNtk) == 1 )
00152 continue;
00153 if ( Abc_ObjIsNode(pObj) && Abc_NodeIsConst(pFanin) )
00154 continue;
00155 if ( Counter++ == Step )
00156 {
00157 *ppObj = pObj;
00158 *ppFanin = pFanin;
00159 return 1;
00160 }
00161 }
00162 return 0;
00163 }
00164
00176 Abc_Ntk_t * Abc_NtkAutoDebugModify( Abc_Ntk_t * pNtkInit, int Step, int fConst1 )
00177 {
00178 extern void Abc_NtkCycleInitStateSop( Abc_Ntk_t * pNtk, int nFrames, int fVerbose );
00179 Abc_Ntk_t * pNtk;
00180 Abc_Obj_t * pObj, * pFanin, * pConst;
00181
00182 pNtk = Abc_NtkDup( pNtkInit );
00183 assert( Abc_NtkNodeNum(pNtk) == Abc_NtkNodeNum(pNtkInit) );
00184
00185 Abc_NtkFindGivenFanin( pNtk, Step, &pObj, &pFanin );
00186
00187 if ( Abc_ObjIsPo(pObj) && Abc_NodeIsConst(pFanin) )
00188 {
00189 Abc_NtkDeleteAll_rec( pObj );
00190 return pNtk;
00191 }
00192
00193 pConst = fConst1? Abc_NtkCreateNodeConst1(pNtk) : Abc_NtkCreateNodeConst0(pNtk);
00194 Abc_ObjTransferFanout( pFanin, pConst );
00195 Abc_NtkDeleteAll_rec( pFanin );
00196
00197 Abc_NtkSweep( pNtk, 0 );
00198 Abc_NtkCleanupSeq( pNtk, 0, 0, 0 );
00199 Abc_NtkToSop( pNtk, 0 );
00200 Abc_NtkCycleInitStateSop( pNtk, 50, 0 );
00201 return pNtk;
00202 }
00203
00207
00208