/**CFile**************************************************************** FileName [resSim.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [Resynthesis package.] Synopsis [Simulation engine.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - January 15, 2007.] Revision [$Id: resSim.c,v 1.00 2007/01/15 00:00:00 alanmi Exp $] ***********************************************************************/ #include "base/abc/abc.h" #include "resInt.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Allocate simulation engine.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ Res_Sim_t * Res_SimAlloc( int nWords ) { Res_Sim_t * p; p = ALLOC( Res_Sim_t, 1 ); memset( p, 0, sizeof(Res_Sim_t) ); // simulation parameters p->nWords = nWords; p->nPats = 8 * sizeof(unsigned) * p->nWords; p->nWordsOut = p->nPats * p->nWords; p->nPatsOut = p->nPats * p->nPats; // simulation info p->vPats = Vec_PtrAllocSimInfo( 1024, p->nWords ); p->vPats0 = Vec_PtrAllocSimInfo( 128, p->nWords ); p->vPats1 = Vec_PtrAllocSimInfo( 128, p->nWords ); p->vOuts = Vec_PtrAllocSimInfo( 128, p->nWordsOut ); // resub candidates p->vCands = Vec_VecStart( 16 ); return p; } /**Function************************************************************* Synopsis [Allocate simulation engine.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimAdjust( Res_Sim_t * p, Abc_Ntk_t * pAig ) { srand( 0xABC ); assert( Abc_NtkIsStrash(pAig) ); p->pAig = pAig; if ( Vec_PtrSize(p->vPats) < Abc_NtkObjNumMax(pAig)+1 ) { Vec_PtrFree( p->vPats ); p->vPats = Vec_PtrAllocSimInfo( Abc_NtkObjNumMax(pAig)+1, p->nWords ); } if ( Vec_PtrSize(p->vPats0) < Abc_NtkPiNum(pAig) ) { Vec_PtrFree( p->vPats0 ); p->vPats0 = Vec_PtrAllocSimInfo( Abc_NtkPiNum(pAig), p->nWords ); } if ( Vec_PtrSize(p->vPats1) < Abc_NtkPiNum(pAig) ) { Vec_PtrFree( p->vPats1 ); p->vPats1 = Vec_PtrAllocSimInfo( Abc_NtkPiNum(pAig), p->nWords ); } if ( Vec_PtrSize(p->vOuts) < Abc_NtkPoNum(pAig) ) { Vec_PtrFree( p->vOuts ); p->vOuts = Vec_PtrAllocSimInfo( Abc_NtkPoNum(pAig), p->nWordsOut ); } // clean storage info for patterns Abc_InfoClear( Vec_PtrEntry(p->vPats0,0), p->nWords * Abc_NtkPiNum(pAig) ); Abc_InfoClear( Vec_PtrEntry(p->vPats1,0), p->nWords * Abc_NtkPiNum(pAig) ); p->nPats0 = 0; p->nPats1 = 0; } /**Function************************************************************* Synopsis [Free simulation engine.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimFree( Res_Sim_t * p ) { Vec_PtrFree( p->vPats ); Vec_PtrFree( p->vPats0 ); Vec_PtrFree( p->vPats1 ); Vec_PtrFree( p->vOuts ); Vec_VecFree( p->vCands ); free( p ); } /**Function************************************************************* Synopsis [Sets random PI simulation info.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimSetRandom( Res_Sim_t * p ) { Abc_Obj_t * pObj; unsigned * pInfo; int i; Abc_NtkForEachPi( p->pAig, pObj, i ) { pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); Abc_InfoRandom( pInfo, p->nWords ); } } /**Function************************************************************* Synopsis [Sets given PI simulation info.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimSetGiven( Res_Sim_t * p, Vec_Ptr_t * vInfo ) { Abc_Obj_t * pObj; unsigned * pInfo, * pInfo2; int i, w; Abc_NtkForEachPi( p->pAig, pObj, i ) { pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); pInfo2 = Vec_PtrEntry( vInfo, i ); for ( w = 0; w < p->nWords; w++ ) pInfo[w] = pInfo2[w]; } } /**Function************************************************************* Synopsis [Simulates one node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimPerformOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ) { unsigned * pInfo, * pInfo1, * pInfo2; int k, fComp1, fComp2; // simulate the internal nodes assert( Abc_ObjIsNode(pNode) ); pInfo = Vec_PtrEntry(vSimInfo, pNode->Id); pInfo1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode)); pInfo2 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId1(pNode)); fComp1 = Abc_ObjFaninC0(pNode); fComp2 = Abc_ObjFaninC1(pNode); if ( fComp1 && fComp2 ) for ( k = 0; k < nSimWords; k++ ) pInfo[k] = ~pInfo1[k] & ~pInfo2[k]; else if ( fComp1 && !fComp2 ) for ( k = 0; k < nSimWords; k++ ) pInfo[k] = ~pInfo1[k] & pInfo2[k]; else if ( !fComp1 && fComp2 ) for ( k = 0; k < nSimWords; k++ ) pInfo[k] = pInfo1[k] & ~pInfo2[k]; else // if ( fComp1 && fComp2 ) for ( k = 0; k < nSimWords; k++ ) pInfo[k] = pInfo1[k] & pInfo2[k]; } /**Function************************************************************* Synopsis [Simulates one CO node.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimTransferOne( Abc_Obj_t * pNode, Vec_Ptr_t * vSimInfo, int nSimWords ) { unsigned * pInfo, * pInfo1; int k, fComp1; // simulate the internal nodes assert( Abc_ObjIsCo(pNode) ); pInfo = Vec_PtrEntry(vSimInfo, pNode->Id); pInfo1 = Vec_PtrEntry(vSimInfo, Abc_ObjFaninId0(pNode)); fComp1 = Abc_ObjFaninC0(pNode); if ( fComp1 ) for ( k = 0; k < nSimWords; k++ ) pInfo[k] = ~pInfo1[k]; else for ( k = 0; k < nSimWords; k++ ) pInfo[k] = pInfo1[k]; } /**Function************************************************************* Synopsis [Performs one round of simulation.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimPerformRound( Res_Sim_t * p ) { Abc_Obj_t * pObj; int i; Abc_InfoFill( Vec_PtrEntry(p->vPats,0), p->nWords ); Abc_AigForEachAnd( p->pAig, pObj, i ) Res_SimPerformOne( pObj, p->vPats, p->nWords ); Abc_NtkForEachPo( p->pAig, pObj, i ) Res_SimTransferOne( pObj, p->vPats, p->nWords ); } /**Function************************************************************* Synopsis [Processes simulation patterns.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimProcessPats( Res_Sim_t * p ) { Abc_Obj_t * pObj; unsigned * pInfoCare, * pInfoNode; int i, j, nDcs = 0; pInfoCare = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 0)->Id ); pInfoNode = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id ); for ( i = 0; i < p->nPats; i++ ) { // skip don't-care patterns if ( !Abc_InfoHasBit(pInfoCare, i) ) { nDcs++; continue; } // separate offset and onset patterns if ( !Abc_InfoHasBit(pInfoNode, i) ) { if ( p->nPats0 >= p->nPats ) continue; Abc_NtkForEachPi( p->pAig, pObj, j ) if ( Abc_InfoHasBit( Vec_PtrEntry(p->vPats, pObj->Id), i ) ) Abc_InfoSetBit( Vec_PtrEntry(p->vPats0, j), p->nPats0 ); p->nPats0++; } else { if ( p->nPats1 >= p->nPats ) continue; Abc_NtkForEachPi( p->pAig, pObj, j ) if ( Abc_InfoHasBit( Vec_PtrEntry(p->vPats, pObj->Id), i ) ) Abc_InfoSetBit( Vec_PtrEntry(p->vPats1, j), p->nPats1 ); p->nPats1++; } } } /**Function************************************************************* Synopsis [Pads the extra space with duplicated simulation info.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimPadSimInfo( Vec_Ptr_t * vPats, int nPats, int nWords ) { unsigned * pInfo; int i, w, iWords; assert( nPats > 0 && nPats < nWords * 8 * (int) sizeof(unsigned) ); // pad the first word if ( nPats < 8 * sizeof(unsigned) ) { Vec_PtrForEachEntry( unsigned *, vPats, pInfo, i ) if ( pInfo[0] & 1 ) pInfo[0] |= ((~0) << nPats); nPats = 8 * sizeof(unsigned); } // pad the empty words iWords = nPats / (8 * sizeof(unsigned)); Vec_PtrForEachEntry( unsigned *, vPats, pInfo, i ) { for ( w = iWords; w < nWords; w++ ) pInfo[w] = pInfo[0]; } } /**Function************************************************************* Synopsis [Duplicates the simulation info to fill the space.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimDeriveInfoReplicate( Res_Sim_t * p ) { unsigned * pInfo, * pInfo2; Abc_Obj_t * pObj; int i, j, w; Abc_NtkForEachPo( p->pAig, pObj, i ) { pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); pInfo2 = Vec_PtrEntry( p->vOuts, i ); for ( j = 0; j < p->nPats; j++ ) for ( w = 0; w < p->nWords; w++ ) *pInfo2++ = pInfo[w]; } } /**Function************************************************************* Synopsis [Complement the simulation info if necessary.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimDeriveInfoComplement( Res_Sim_t * p ) { unsigned * pInfo, * pInfo2; Abc_Obj_t * pObj; int i, j, w; Abc_NtkForEachPo( p->pAig, pObj, i ) { pInfo = Vec_PtrEntry( p->vPats, pObj->Id ); pInfo2 = Vec_PtrEntry( p->vOuts, i ); for ( j = 0; j < p->nPats; j++, pInfo2 += p->nWords ) if ( Abc_InfoHasBit( pInfo, j ) ) for ( w = 0; w < p->nWords; w++ ) pInfo2[w] = ~pInfo2[w]; } } /**Function************************************************************* Synopsis [Free simulation engine.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimReportOne( Res_Sim_t * p ) { unsigned * pInfoCare, * pInfoNode; int i, nDcs, nOnes, nZeros; pInfoCare = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 0)->Id ); pInfoNode = Vec_PtrEntry( p->vPats, Abc_NtkPo(p->pAig, 1)->Id ); nDcs = nOnes = nZeros = 0; for ( i = 0; i < p->nPats; i++ ) { // skip don't-care patterns if ( !Abc_InfoHasBit(pInfoCare, i) ) { nDcs++; continue; } // separate offset and onset patterns if ( !Abc_InfoHasBit(pInfoNode, i) ) nZeros++; else nOnes++; } printf( "On = %3d (%7.2f %%) ", nOnes, 100.0*nOnes/p->nPats ); printf( "Off = %3d (%7.2f %%) ", nZeros, 100.0*nZeros/p->nPats ); printf( "Dc = %3d (%7.2f %%) ", nDcs, 100.0*nDcs/p->nPats ); printf( "P0 = %3d ", p->nPats0 ); printf( "P1 = %3d ", p->nPats1 ); if ( p->nPats0 < 4 || p->nPats1 < 4 ) printf( "*" ); printf( "\n" ); } /**Function************************************************************* Synopsis [Prints output patterns.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Res_SimPrintOutPatterns( Res_Sim_t * p, Abc_Ntk_t * pAig ) { Abc_Obj_t * pObj; unsigned * pInfo2; int i; Abc_NtkForEachPo( pAig, pObj, i ) { pInfo2 = Vec_PtrEntry( p->vOuts, i ); Extra_PrintBinary( stdout, pInfo2, p->nPatsOut ); printf( "\n" ); } } /**Function************************************************************* Synopsis [Prepares simulation info for candidate filtering.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Res_SimPrepare( Res_Sim_t * p, Abc_Ntk_t * pAig, int nTruePis, int fVerbose ) { int Limit; // prepare the manager Res_SimAdjust( p, pAig ); // collect 0/1 simulation info for ( Limit = 0; Limit < 10; Limit++ ) { Res_SimSetRandom( p ); Res_SimPerformRound( p ); Res_SimProcessPats( p ); if ( !(p->nPats0 < p->nPats || p->nPats1 < p->nPats) ) break; } // printf( "%d ", Limit ); // report the last set of patterns // Res_SimReportOne( p ); // printf( "\n" ); // quit if there is not enough // if ( p->nPats0 < 4 || p->nPats1 < 4 ) if ( p->nPats0 < 4 || p->nPats1 < 4 ) { // Res_SimReportOne( p ); return 0; } // create bit-matrix info if ( p->nPats0 < p->nPats ) Res_SimPadSimInfo( p->vPats0, p->nPats0, p->nWords ); if ( p->nPats1 < p->nPats ) Res_SimPadSimInfo( p->vPats1, p->nPats1, p->nWords ); // resimulate 0-patterns Res_SimSetGiven( p, p->vPats0 ); Res_SimPerformRound( p ); Res_SimDeriveInfoReplicate( p ); // resimulate 1-patterns Res_SimSetGiven( p, p->vPats1 ); Res_SimPerformRound( p ); Res_SimDeriveInfoComplement( p ); // print output patterns // Res_SimPrintOutPatterns( p, pAig ); return 1; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END