| /**CFile**************************************************************** |
| |
| FileName [wlcSim.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Verilog parser.] |
| |
| Synopsis [Performs sequential simulation of word-level network.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 04, 2015.] |
| |
| Revision [$Id: wlcSim.c,v 1.00 2015/06/04 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "wlc.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Internal simulation APIs.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| static inline word * Wlc_ObjSim( Gia_Man_t * p, int iObj ) |
| { |
| return Vec_WrdEntryP( p->vSims, p->nSimWords * iObj ); |
| } |
| static inline void Wlc_ObjSimPi( Gia_Man_t * p, int iObj ) |
| { |
| int w; |
| word * pSim = Wlc_ObjSim( p, iObj ); |
| for ( w = 0; w < p->nSimWords; w++ ) |
| pSim[w] = Gia_ManRandomW( 0 ); |
| } |
| static inline void Wlc_ObjSimRo( Gia_Man_t * p, int iObj ) |
| { |
| int w; |
| word * pSimRo = Wlc_ObjSim( p, iObj ); |
| word * pSimRi = Wlc_ObjSim( p, Gia_ObjRoToRiId(p, iObj) ); |
| for ( w = 0; w < p->nSimWords; w++ ) |
| pSimRo[w] = pSimRi[w]; |
| } |
| static inline void Wlc_ObjSimCo( Gia_Man_t * p, int iObj ) |
| { |
| int w; |
| Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); |
| word * pSimCo = Wlc_ObjSim( p, iObj ); |
| word * pSimDri = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); |
| if ( Gia_ObjFaninC0(pObj) ) |
| for ( w = 0; w < p->nSimWords; w++ ) |
| pSimCo[w] = ~pSimDri[w]; |
| else |
| for ( w = 0; w < p->nSimWords; w++ ) |
| pSimCo[w] = pSimDri[w]; |
| } |
| static inline void Wlc_ObjSimAnd( Gia_Man_t * p, int iObj ) |
| { |
| int w; |
| Gia_Obj_t * pObj = Gia_ManObj( p, iObj ); |
| word * pSim = Wlc_ObjSim( p, iObj ); |
| word * pSim0 = Wlc_ObjSim( p, Gia_ObjFaninId0(pObj, iObj) ); |
| word * pSim1 = Wlc_ObjSim( p, Gia_ObjFaninId1(pObj, iObj) ); |
| if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) |
| for ( w = 0; w < p->nSimWords; w++ ) |
| pSim[w] = ~pSim0[w] & ~pSim1[w]; |
| else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) |
| for ( w = 0; w < p->nSimWords; w++ ) |
| pSim[w] = ~pSim0[w] & pSim1[w]; |
| else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) |
| for ( w = 0; w < p->nSimWords; w++ ) |
| pSim[w] = pSim0[w] & ~pSim1[w]; |
| else |
| for ( w = 0; w < p->nSimWords; w++ ) |
| pSim[w] = pSim0[w] & pSim1[w]; |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Performs simulation of a word-level network.] |
| |
| Description [Returns vRes, a 2D array of simulation information for |
| the output of each bit of each object listed in vNodes. In particular, |
| Vec_Ptr_t * vSimObj = (Vec_Ptr_t *)Vec_PtrEntry(vRes, iObj) and |
| Vec_Ptr_t * vSimObjBit = (Vec_Ptr_t *)Vec_PtrEntry(vSimObj, iBit) |
| are arrays containing the simulation info for each object (vSimObj) |
| and for each output bit of this object (vSimObjBit). Alternatively, |
| Vec_Ptr_t * vSimObjBit = Vec_VecEntryEntry( (Vec_Vec_t *)vRes, iObj, iBit ). |
| The output bitwidth of an object is Wlc_ObjRange( Wlc_NtkObj(pNtk, iObj) ). |
| Simulation information is binary data constaining the given number (nWords) |
| of 64-bit machine words for the given number (nFrames) of consecutive |
| timeframes. The total number of timeframes is nWords * nFrames for |
| each bit of each object.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Wlc_NtkDeleteSim( Vec_Ptr_t * p ) |
| { |
| word * pInfo; int i, k; |
| Vec_Vec_t * vVec = (Vec_Vec_t *)p; |
| Vec_VecForEachEntry( word *, vVec, pInfo, i, k ) |
| ABC_FREE( pInfo ); |
| Vec_VecFree( vVec ); |
| } |
| Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int nFrames ) |
| { |
| Gia_Obj_t * pObj; |
| Vec_Ptr_t * vOne, * vRes; |
| Gia_Man_t * pGia = Wlc_NtkBitBlast( p, NULL ); |
| Wlc_Obj_t * pWlcObj; |
| int f, i, k, w, nBits, Counter = 0; |
| // allocate simulation info for one timeframe |
| Vec_WrdFreeP( &pGia->vSims ); |
| pGia->vSims = Vec_WrdStart( Gia_ManObjNum(pGia) * nWords ); |
| pGia->nSimWords = nWords; |
| // allocate resulting simulation info |
| vRes = Vec_PtrAlloc( Vec_IntSize(vNodes) ); |
| Wlc_NtkForEachObjVec( vNodes, p, pWlcObj, i ) |
| { |
| nBits = Wlc_ObjRange(pWlcObj); |
| vOne = Vec_PtrAlloc( nBits ); |
| for ( k = 0; k < nBits; k++ ) |
| Vec_PtrPush( vOne, ABC_CALLOC(word, nWords * nFrames) ); |
| Vec_PtrPush( vRes, vOne ); |
| } |
| // perform simulation (const0 and flop outputs are already initialized) |
| Gia_ManRandomW( 1 ); |
| for ( f = 0; f < nFrames; f++ ) |
| { |
| Gia_ManForEachObj1( pGia, pObj, i ) |
| { |
| if ( Gia_ObjIsAnd(pObj) ) |
| Wlc_ObjSimAnd( pGia, i ); |
| else if ( Gia_ObjIsCo(pObj) ) |
| Wlc_ObjSimCo( pGia, i ); |
| else if ( Gia_ObjIsPi(pGia, pObj) ) |
| Wlc_ObjSimPi( pGia, i ); |
| else if ( Gia_ObjIsRo(pGia, pObj) ) |
| Wlc_ObjSimRo( pGia, i ); |
| } |
| // collect simulation data |
| Wlc_NtkForEachObjVec( vNodes, p, pWlcObj, i ) |
| { |
| int nBits = Wlc_ObjRange(pWlcObj); |
| int iFirst = Vec_IntEntry( &p->vCopies, Wlc_ObjId(p, pWlcObj) ); |
| for ( k = 0; k < nBits; k++ ) |
| { |
| int iLit = Vec_IntEntry( &p->vBits, iFirst + k ); |
| word * pInfo = (word*)Vec_VecEntryEntry( (Vec_Vec_t *)vRes, i, k ); |
| if ( iLit == -1 ) |
| { |
| Counter++; |
| for ( w = 0; w < nWords; w++ ) |
| pInfo[f * nWords + w] = 0; |
| } |
| else |
| { |
| word * pInfoObj = Wlc_ObjSim( pGia, Abc_Lit2Var(iLit) ); |
| for ( w = 0; w < nWords; w++ ) |
| pInfo[f * nWords + w] = Abc_LitIsCompl(iLit) ? ~pInfoObj[w] : pInfoObj[w]; |
| } |
| } |
| } |
| if ( f == 0 && Counter ) |
| printf( "Replaced %d dangling internal bits with constant 0.\n", Counter ); |
| } |
| Vec_WrdFreeP( &pGia->vSims ); |
| pGia->nSimWords = 0; |
| Gia_ManStop( pGia ); |
| return vRes; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Testing procedure.] |
| |
| Description [This testing procedure assumes that the WLC network has |
| one node, which is a multiplier. It simulates the node and checks the |
| word-level interpretation of the bit-level simulation info to make sure |
| that it indeed represents multiplication.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Wlc_NtkSimulatePrint( Wlc_Ntk_t * p, Vec_Int_t * vNodes, Vec_Ptr_t * vRes, int nWords, int nFrames ) |
| { |
| Wlc_Obj_t * pWlcObj; |
| int f, w, b, i, k, iPat = 0; |
| for ( f = 0; f < nFrames; f++, printf("\n") ) |
| for ( w = 0; w < nWords; w++ ) |
| for ( b = 0; b < 64; b++, iPat++, printf("\n") ) |
| { |
| Wlc_NtkForEachObjVec( vNodes, p, pWlcObj, i ) |
| { |
| int nBits = Wlc_ObjRange(pWlcObj); |
| for ( k = nBits-1; k >= 0; k-- ) |
| { |
| word * pInfo = (word*)Vec_VecEntryEntry( (Vec_Vec_t *)vRes, i, k ); |
| printf( "%d", Abc_InfoHasBit((unsigned *)pInfo, iPat) ); |
| } |
| printf( " " ); |
| } |
| } |
| } |
| void Wlc_NtkSimulateTest( Wlc_Ntk_t * p ) |
| { |
| int nWords = 2; |
| int nFrames = 2; |
| Vec_Ptr_t * vRes; |
| Vec_Int_t * vNodes = Vec_IntAlloc( 3 ); |
| Vec_IntPush( vNodes, 1 ); |
| Vec_IntPush( vNodes, 2 ); |
| Vec_IntPush( vNodes, 3 ); |
| vRes = Wlc_NtkSimulate( p, vNodes, nWords, nFrames ); |
| Wlc_NtkSimulatePrint( p, vNodes, vRes, nWords, nFrames ); |
| Wlc_NtkDeleteSim( vRes ); |
| Vec_IntFree( vNodes ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |