/**CFile**************************************************************** FileName [abcDebug.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Network and node package.] Synopsis [Automated debugging procedures.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - June 20, 2005.] Revision [$Id: abcDebug.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "base/abc/abc.h" #include "base/io/ioAbc.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// static int Abc_NtkCountFaninsTotal( Abc_Ntk_t * pNtk ); static Abc_Ntk_t * Abc_NtkAutoDebugModify( Abc_Ntk_t * pNtk, int ObjNum, int fConst1 ); //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Takes a network and a procedure to test.] Description [The network demonstrates the bug in the procedure. Procedure should return 1 if the bug is demonstrated.] SideEffects [] SeeAlso [] ***********************************************************************/ void Abc_NtkAutoDebug( Abc_Ntk_t * pNtk, int (*pFuncError) (Abc_Ntk_t *) ) { Abc_Ntk_t * pNtkMod; char * pFileName = "bug_found.blif"; int i, nSteps, nIter, ModNum, RandNum = 1; abctime clk, clkTotal = Abc_Clock(); assert( Abc_NtkIsLogic(pNtk) ); srand( 0x123123 ); // create internal copy of the network pNtk = Abc_NtkDup(pNtk); if ( !(*pFuncError)( pNtk ) ) { printf( "The original network does not cause the bug. Quitting.\n" ); Abc_NtkDelete( pNtk ); return; } // perform incremental modifications for ( nIter = 0; ; nIter++ ) { clk = Abc_Clock(); // count how many ways of modifying the network exists nSteps = 2 * Abc_NtkCountFaninsTotal(pNtk); // try modifying the network as many times RandNum ^= rand(); for ( i = 0; i < nSteps; i++ ) { // get the shifted number of bug ModNum = (i + RandNum) % nSteps; // get the modified network pNtkMod = Abc_NtkAutoDebugModify( pNtk, ModNum/2, ModNum%2 ); // write the network Io_WriteBlifLogic( pNtk, "bug_temp.blif", 1 ); // check if the bug is still there if ( (*pFuncError)( pNtkMod ) ) // bug is still there { Abc_NtkDelete( pNtk ); pNtk = pNtkMod; break; } else // no bug Abc_NtkDelete( pNtkMod ); } printf( "Iter %6d : Latches = %6d. Nodes = %6d. Steps = %6d. Error step = %3d. ", nIter, Abc_NtkLatchNum(pNtk), Abc_NtkNodeNum(pNtk), nSteps, i ); ABC_PRT( "Time", Abc_Clock() - clk ); if ( i == nSteps ) // could not modify it while preserving the bug break; } // write out the final network Io_WriteBlifLogic( pNtk, pFileName, 1 ); printf( "Final network written into file \"%s\". ", pFileName ); ABC_PRT( "Total time", Abc_Clock() - clkTotal ); Abc_NtkDelete( pNtk ); } /**Function************************************************************* Synopsis [Counts the total number of fanins.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkCountFaninsTotal( Abc_Ntk_t * pNtk ) { Abc_Obj_t * pObj, * pFanin; int i, k, Counter = 0; Abc_NtkForEachObj( pNtk, pObj, i ) Abc_ObjForEachFanin( pObj, pFanin, k ) { if ( !Abc_ObjIsNode(pObj) && !Abc_ObjIsPo(pObj) ) continue; if ( Abc_ObjIsPo(pObj) && Abc_NtkPoNum(pNtk) == 1 ) continue; if ( Abc_ObjIsNode(pObj) && Abc_NodeIsConst(pFanin) ) continue; Counter++; } return Counter; } /**Function************************************************************* Synopsis [Returns the node and fanin to be modified.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Abc_NtkFindGivenFanin( Abc_Ntk_t * pNtk, int Step, Abc_Obj_t ** ppObj, Abc_Obj_t ** ppFanin ) { Abc_Obj_t * pObj, * pFanin; int i, k, Counter = 0; Abc_NtkForEachObj( pNtk, pObj, i ) Abc_ObjForEachFanin( pObj, pFanin, k ) { if ( !Abc_ObjIsNode(pObj) && !Abc_ObjIsPo(pObj) ) continue; if ( Abc_ObjIsPo(pObj) && Abc_NtkPoNum(pNtk) == 1 ) continue; if ( Abc_ObjIsNode(pObj) && Abc_NodeIsConst(pFanin) ) continue; if ( Counter++ == Step ) { *ppObj = pObj; *ppFanin = pFanin; return 1; } } return 0; } /**Function************************************************************* Synopsis [Perform modification with the given number.] Description [Modification consists of replacing the node by a constant.] SideEffects [] SeeAlso [] ***********************************************************************/ Abc_Ntk_t * Abc_NtkAutoDebugModify( Abc_Ntk_t * pNtkInit, int Step, int fConst1 ) { extern void Abc_NtkCycleInitStateSop( Abc_Ntk_t * pNtk, int nFrames, int fVerbose ); Abc_Ntk_t * pNtk; Abc_Obj_t * pObj, * pFanin, * pConst; // copy the network pNtk = Abc_NtkDup( pNtkInit ); assert( Abc_NtkNodeNum(pNtk) == Abc_NtkNodeNum(pNtkInit) ); // find the object number Abc_NtkFindGivenFanin( pNtk, Step, &pObj, &pFanin ); // consider special case if ( Abc_ObjIsPo(pObj) && Abc_NodeIsConst(pFanin) ) { Abc_NtkDeleteAll_rec( pObj ); return pNtk; } // plug in a constant node pConst = fConst1? Abc_NtkCreateNodeConst1(pNtk) : Abc_NtkCreateNodeConst0(pNtk); Abc_ObjTransferFanout( pFanin, pConst ); Abc_NtkDeleteAll_rec( pFanin ); Abc_NtkSweep( pNtk, 0 ); Abc_NtkCleanupSeq( pNtk, 0, 0, 0 ); Abc_NtkToSop( pNtk, 0 ); Abc_NtkCycleInitStateSop( pNtk, 50, 0 ); return pNtk; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END