| /**CFile**************************************************************** |
| |
| FileName [fsimSim.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Fast sequential AIG simulator.] |
| |
| Synopsis [Simulation procedures.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: fsimSim.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "fsimInt.h" |
| #include "aig/ssw/ssw.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimInfoRandom( Fsim_Man_t * p, unsigned * pInfo ) |
| { |
| int w; |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = Aig_ManRandom( 0 ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimInfoZero( Fsim_Man_t * p, unsigned * pInfo ) |
| { |
| int w; |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns index of the first pattern that failed.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Fsim_ManSimInfoIsZero( Fsim_Man_t * p, unsigned * pInfo ) |
| { |
| int w; |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| if ( pInfo[w] ) |
| return 32*(w-1) + Aig_WordFindFirstBit( pInfo[w] ); |
| return -1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimInfoOne( Fsim_Man_t * p, unsigned * pInfo ) |
| { |
| int w; |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = ~0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimInfoCopy( Fsim_Man_t * p, unsigned * pInfo, unsigned * pInfo0 ) |
| { |
| int w; |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = pInfo0[w]; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimulateCi( Fsim_Man_t * p, int iNode, int iCi ) |
| { |
| unsigned * pInfo = Fsim_SimData( p, iNode % p->nFront ); |
| unsigned * pInfo0 = Fsim_SimDataCi( p, iCi ); |
| int w; |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = pInfo0[w]; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimulateCo( Fsim_Man_t * p, int iCo, int iFan0 ) |
| { |
| unsigned * pInfo = Fsim_SimDataCo( p, iCo ); |
| unsigned * pInfo0 = Fsim_SimData( p, Fsim_Lit2Var(iFan0) % p->nFront ); |
| int w; |
| if ( Fsim_LitIsCompl(iFan0) ) |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = ~pInfo0[w]; |
| else //if ( !Fsim_LitIsCompl(iFan0) ) |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = pInfo0[w]; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimulateNode( Fsim_Man_t * p, int iNode, int iFan0, int iFan1 ) |
| { |
| unsigned * pInfo = Fsim_SimData( p, iNode % p->nFront ); |
| unsigned * pInfo0 = Fsim_SimData( p, Fsim_Lit2Var(iFan0) % p->nFront ); |
| unsigned * pInfo1 = Fsim_SimData( p, Fsim_Lit2Var(iFan1) % p->nFront ); |
| int w; |
| if ( Fsim_LitIsCompl(iFan0) && Fsim_LitIsCompl(iFan1) ) |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = ~(pInfo0[w] | pInfo1[w]); |
| else if ( Fsim_LitIsCompl(iFan0) && !Fsim_LitIsCompl(iFan1) ) |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = ~pInfo0[w] & pInfo1[w]; |
| else if ( !Fsim_LitIsCompl(iFan0) && Fsim_LitIsCompl(iFan1) ) |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = pInfo0[w] & ~pInfo1[w]; |
| else //if ( !Fsim_LitIsCompl(iFan0) && !Fsim_LitIsCompl(iFan1) ) |
| for ( w = p->nWords-1; w >= 0; w-- ) |
| pInfo[w] = pInfo0[w] & pInfo1[w]; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimInfoInit( Fsim_Man_t * p ) |
| { |
| int iPioNum, i; |
| Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i ) |
| { |
| if ( iPioNum < p->nPis ) |
| Fsim_ManSimInfoRandom( p, Fsim_SimDataCi(p, i) ); |
| else |
| Fsim_ManSimInfoZero( p, Fsim_SimDataCi(p, i) ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimInfoTransfer( Fsim_Man_t * p ) |
| { |
| int iPioNum, i; |
| Vec_IntForEachEntry( p->vCis2Ids, iPioNum, i ) |
| { |
| if ( iPioNum < p->nPis ) |
| Fsim_ManSimInfoRandom( p, Fsim_SimDataCi(p, i) ); |
| else |
| Fsim_ManSimInfoCopy( p, Fsim_SimDataCi(p, i), Fsim_SimDataCo(p, p->nPos+iPioNum-p->nPis) ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Fsim_ManRestoreNum( Fsim_Man_t * p ) |
| { |
| int ch, i, x = 0; |
| for ( i = 0; (ch = *p->pDataCur++) & 0x80; i++ ) |
| x |= (ch & 0x7f) << (7 * i); |
| assert( p->pDataCur - p->pDataAig < p->nDataAig ); |
| return x | (ch << (7 * i)); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Fsim_ManRestoreObj( Fsim_Man_t * p, Fsim_Obj_t * pObj ) |
| { |
| int iValue = Fsim_ManRestoreNum( p ); |
| if ( (iValue & 3) == 3 ) // and |
| { |
| pObj->iNode = (iValue >> 2) + p->iNodePrev; |
| pObj->iFan0 = (pObj->iNode << 1) - Fsim_ManRestoreNum( p ); |
| pObj->iFan1 = pObj->iFan0 - Fsim_ManRestoreNum( p ); |
| p->iNodePrev = pObj->iNode; |
| } |
| else if ( (iValue & 3) == 1 ) // ci |
| { |
| pObj->iNode = (iValue >> 2) + p->iNodePrev; |
| pObj->iFan0 = 0; |
| pObj->iFan1 = 0; |
| p->iNodePrev = pObj->iNode; |
| } |
| else // if ( (iValue & 1) == 0 ) // co |
| { |
| pObj->iNode = 0; |
| pObj->iFan0 = ((p->iNodePrev << 1) | 1) - (iValue >> 1); |
| pObj->iFan1 = 0; |
| } |
| return 1; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimulateRound2( Fsim_Man_t * p ) |
| { |
| Fsim_Obj_t * pObj; |
| int i, iCis = 0, iCos = 0; |
| if ( Aig_ObjRefs(Aig_ManConst1(p->pAig)) ) |
| Fsim_ManSimInfoOne( p, Fsim_SimData(p, 1) ); |
| Fsim_ManForEachObj( p, pObj, i ) |
| { |
| if ( pObj->iFan0 == 0 ) |
| Fsim_ManSimulateCi( p, pObj->iNode, iCis++ ); |
| else if ( pObj->iFan1 == 0 ) |
| Fsim_ManSimulateCo( p, iCos++, pObj->iFan0 ); |
| else |
| Fsim_ManSimulateNode( p, pObj->iNode, pObj->iFan0, pObj->iFan1 ); |
| } |
| assert( iCis == p->nCis ); |
| assert( iCos == p->nCos ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline void Fsim_ManSimulateRound( Fsim_Man_t * p ) |
| { |
| int * pCur, * pEnd; |
| int iCis = 0, iCos = 0; |
| if ( p->pDataAig2 == NULL ) |
| { |
| Fsim_ManSimulateRound2( p ); |
| return; |
| } |
| if ( Aig_ObjRefs(Aig_ManConst1(p->pAig)) ) |
| Fsim_ManSimInfoOne( p, Fsim_SimData(p, 1) ); |
| pCur = p->pDataAig2 + 6; |
| pEnd = p->pDataAig2 + 3 * p->nObjs; |
| while ( pCur < pEnd ) |
| { |
| if ( pCur[1] == 0 ) |
| Fsim_ManSimulateCi( p, pCur[0], iCis++ ); |
| else if ( pCur[2] == 0 ) |
| Fsim_ManSimulateCo( p, iCos++, pCur[1] ); |
| else |
| Fsim_ManSimulateNode( p, pCur[0], pCur[1], pCur[2] ); |
| pCur += 3; |
| } |
| assert( iCis == p->nCis ); |
| assert( iCos == p->nCos ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Fsim_ManSimulateRoundTest( Fsim_Man_t * p ) |
| { |
| Fsim_Obj_t * pObj; |
| int i; |
| clock_t clk = clock(); |
| Fsim_ManForEachObj( p, pObj, i ) |
| { |
| } |
| // ABC_PRT( "Unpacking time", p->pPars->nIters * (clock() - clk) ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns index of the PO and pattern that failed it.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline int Fsim_ManCheckPos( Fsim_Man_t * p, int * piPo, int * piPat ) |
| { |
| int i, iPat; |
| for ( i = 0; i < p->nPos; i++ ) |
| { |
| iPat = Fsim_ManSimInfoIsZero( p, Fsim_SimDataCo(p, i) ); |
| if ( iPat >= 0 ) |
| { |
| *piPo = i; |
| *piPat = iPat; |
| return 1; |
| } |
| } |
| return 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Returns the counter-example.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Abc_Cex_t * Fsim_ManGenerateCounter( Aig_Man_t * pAig, int iFrame, int iOut, int nWords, int iPat, Vec_Int_t * vCis2Ids ) |
| { |
| Abc_Cex_t * p; |
| unsigned * pData; |
| int f, i, w, iPioId, Counter; |
| p = Abc_CexAlloc( Aig_ManRegNum(pAig), Saig_ManPiNum(pAig), iFrame+1 ); |
| p->iFrame = iFrame; |
| p->iPo = iOut; |
| // fill in the binary data |
| Aig_ManRandom( 1 ); |
| Counter = p->nRegs; |
| pData = ABC_ALLOC( unsigned, nWords ); |
| for ( f = 0; f <= iFrame; f++, Counter += p->nPis ) |
| for ( i = 0; i < Aig_ManPiNum(pAig); i++ ) |
| { |
| iPioId = Vec_IntEntry( vCis2Ids, i ); |
| if ( iPioId >= p->nPis ) |
| continue; |
| for ( w = nWords-1; w >= 0; w-- ) |
| pData[w] = Aig_ManRandom( 0 ); |
| if ( Aig_InfoHasBit( pData, iPat ) ) |
| Aig_InfoSetBit( p->pData, Counter + iPioId ); |
| } |
| ABC_FREE( pData ); |
| return p; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| int Fsim_ManSimulate( Aig_Man_t * pAig, Fsim_ParSim_t * pPars ) |
| { |
| Fsim_Man_t * p; |
| Sec_MtrStatus_t Status; |
| int i, iOut, iPat; |
| clock_t clk, clkTotal = clock(), clk2, clk2Total = 0; |
| assert( Aig_ManRegNum(pAig) > 0 ); |
| if ( pPars->fCheckMiter ) |
| { |
| Status = Sec_MiterStatus( pAig ); |
| if ( Status.nSat > 0 ) |
| { |
| printf( "Miter is trivially satisfiable (output %d).\n", Status.iOut ); |
| return 1; |
| } |
| if ( Status.nUndec == 0 ) |
| { |
| printf( "Miter is trivially unsatisfiable.\n" ); |
| return 0; |
| } |
| } |
| // create manager |
| clk = clock(); |
| p = Fsim_ManCreate( pAig ); |
| p->nWords = pPars->nWords; |
| if ( pPars->fVerbose ) |
| { |
| printf( "Obj = %8d (%8d). Cut = %6d. Front = %6d. FrtMem = %7.2f MB. ", |
| p->nObjs, p->nCis + p->nNodes, p->nCrossCutMax, p->nFront, |
| 4.0*p->nWords*(p->nFront)/(1<<20) ); |
| ABC_PRT( "Time", clock() - clk ); |
| } |
| // create simulation frontier |
| clk = clock(); |
| Fsim_ManFront( p, pPars->fCompressAig ); |
| if ( pPars->fVerbose ) |
| { |
| printf( "Max ID = %8d. Log max ID = %2d. AigMem = %7.2f MB (%5.2f byte/obj). ", |
| p->iNumber, Aig_Base2Log(p->iNumber), |
| 1.0*(p->pDataCur-p->pDataAig)/(1<<20), |
| 1.0*(p->pDataCur-p->pDataAig)/p->nObjs ); |
| ABC_PRT( "Time", clock() - clk ); |
| } |
| // perform simulation |
| Aig_ManRandom( 1 ); |
| assert( p->pDataSim == NULL ); |
| p->pDataSim = ABC_ALLOC( unsigned, p->nWords * p->nFront ); |
| p->pDataSimCis = ABC_ALLOC( unsigned, p->nWords * p->nCis ); |
| p->pDataSimCos = ABC_ALLOC( unsigned, p->nWords * p->nCos ); |
| Fsim_ManSimInfoInit( p ); |
| for ( i = 0; i < pPars->nIters; i++ ) |
| { |
| Fsim_ManSimulateRound( p ); |
| if ( pPars->fVerbose ) |
| { |
| printf( "Frame %4d out of %4d and timeout %3d sec. ", i+1, pPars->nIters, pPars->TimeLimit ); |
| printf( "Time = %7.2f sec\r", (1.0*clock()-clkTotal)/CLOCKS_PER_SEC ); |
| } |
| if ( pPars->fCheckMiter && Fsim_ManCheckPos( p, &iOut, &iPat ) ) |
| { |
| assert( pAig->pSeqModel == NULL ); |
| pAig->pSeqModel = Fsim_ManGenerateCounter( pAig, i, iOut, p->nWords, iPat, p->vCis2Ids ); |
| if ( pPars->fVerbose ) |
| printf( "Miter is satisfiable after simulation (output %d).\n", iOut ); |
| break; |
| } |
| if ( (clock() - clkTotal)/CLOCKS_PER_SEC >= pPars->TimeLimit ) |
| break; |
| clk2 = clock(); |
| if ( i < pPars->nIters - 1 ) |
| Fsim_ManSimInfoTransfer( p ); |
| clk2Total += clock() - clk2; |
| } |
| if ( pAig->pSeqModel == NULL ) |
| printf( "No bug detected after %d frames with time limit %d seconds.\n", i+1, pPars->TimeLimit ); |
| if ( pPars->fVerbose ) |
| { |
| printf( "Maxcut = %8d. AigMem = %7.2f MB. SimMem = %7.2f MB. ", |
| p->nCrossCutMax, |
| p->pDataAig2? 12.0*p->nObjs/(1<<20) : 1.0*(p->pDataCur-p->pDataAig)/(1<<20), |
| 4.0*p->nWords*(p->nFront+p->nCis+p->nCos)/(1<<20) ); |
| ABC_PRT( "Sim time", clock() - clkTotal ); |
| |
| // ABC_PRT( "Additional time", clk2Total ); |
| // Fsim_ManSimulateRoundTest( p ); |
| // Fsim_ManSimulateRoundTest2( p ); |
| } |
| Fsim_ManDelete( p ); |
| return pAig->pSeqModel != NULL; |
| |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |