From 0489deb631099e725a83cfa92b251b4cc91bfc5e Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Thu, 4 Jun 2015 22:32:51 -0700 Subject: Sequential word-level simulator for Wlc_Ntk_t. --- src/base/wlc/module.make | 1 + src/base/wlc/wlc.h | 4 + src/base/wlc/wlcBlast.c | 11 ++- src/base/wlc/wlcCom.c | 2 + src/base/wlc/wlcNtk.c | 1 + src/base/wlc/wlcSim.c | 251 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 266 insertions(+), 4 deletions(-) create mode 100644 src/base/wlc/wlcSim.c (limited to 'src/base/wlc') diff --git a/src/base/wlc/module.make b/src/base/wlc/module.make index 6945046a..f3aa6871 100644 --- a/src/base/wlc/module.make +++ b/src/base/wlc/module.make @@ -4,5 +4,6 @@ SRC += src/base/wlc/wlcAbs.c \ src/base/wlc/wlcNtk.c \ src/base/wlc/wlcReadSmt.c \ src/base/wlc/wlcReadVer.c \ + src/base/wlc/wlcSim.c \ src/base/wlc/wlcStdin.c \ src/base/wlc/wlcWriteVer.c diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 237e1dac..54dccc1f 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -141,6 +141,7 @@ struct Wlc_Ntk_t_ int nTravIds; // counter of traversal IDs Vec_Int_t vTravIds; // trav IDs of the objects Vec_Int_t vCopies; // object first bits + Vec_Int_t vBits; // object mapping into AIG nodes }; static inline int Wlc_NtkObjNum( Wlc_Ntk_t * p ) { return p->iObj - 1; } @@ -260,6 +261,9 @@ extern void Wlc_NtkTransferNames( Wlc_Ntk_t * pNew, Wlc_Ntk_t * p ); /*=== wlcReadSmt.c ========================================================*/ extern Wlc_Ntk_t * Wlc_ReadSmtBuffer( char * pFileName, char * pBuffer, char * pLimit ); extern Wlc_Ntk_t * Wlc_ReadSmt( char * pFileName ); +/*=== wlcSim.c ========================================================*/ +extern Vec_Ptr_t * Wlc_NtkSimulate( Wlc_Ntk_t * p, Vec_Int_t * vNodes, int nWords, int nFrames ); +extern void Wlc_NtkDeleteSim( Vec_Ptr_t * p ); /*=== wlcStdin.c ========================================================*/ extern int Wlc_StdinProcessSmt( Abc_Frame_t * pAbc, char * pCmd ); /*=== wlcReadVer.c ========================================================*/ diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index a4e5459e..c15c0fa8 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -412,13 +412,14 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds ) Tim_Man_t * pManTime = NULL; Gia_Man_t * pTemp, * pNew, * pExtra = NULL; Wlc_Obj_t * pObj, * pPrev = NULL; - Vec_Int_t * vBits, * vTemp0, * vTemp1, * vTemp2, * vRes; + Vec_Int_t * vBits = &p->vBits, * vTemp0, * vTemp1, * vTemp2, * vRes; int nBits = Wlc_NtkPrepareBits( p ); int nRange, nRange0, nRange1, nRange2; int i, k, b, iFanin, iLit, nAndPrev, * pFans0, * pFans1, * pFans2; int nFFins = 0, nFFouts = 0, curPi = 0, curPo = 0; int nBitCis = 0, nBitCos = 0; - vBits = Vec_IntAlloc( nBits ); + Vec_IntClear( vBits ); + Vec_IntGrow( vBits, nBits ); vTemp0 = Vec_IntAlloc( 1000 ); vTemp1 = Vec_IntAlloc( 1000 ); vTemp2 = Vec_IntAlloc( 1000 ); @@ -781,13 +782,14 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds ) } if ( fVerbose ) printf( "\n" ); - Vec_IntFree( vBits ); - Vec_IntErase( &p->vCopies ); + //Vec_IntErase( vBits ); + //Vec_IntErase( &p->vCopies ); // set the number of registers assert( nFFins == nFFouts ); Gia_ManSetRegNum( pNew, nFFins ); // finalize AIG pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManDupRemapLiterals( vBits, pTemp ); Gia_ManStop( pTemp ); // transform AIG with init state if ( p->pInits ) @@ -800,6 +802,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Vec_Int_t * vBoxIds ) else { pNew = Gia_ManDupZeroUndc( pTemp = pNew, p->pInits, 1 ); + Gia_ManDupRemapLiterals( vBits, pTemp ); Gia_ManStop( pTemp ); } } diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 3681d41b..16e2c497 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -358,6 +358,7 @@ usage: ******************************************************************************/ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) { + extern void Wlc_NtkSimulateTest( Wlc_Ntk_t * p ); Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); int c, fVerbose = 0; Extra_UtilGetoptReset(); @@ -384,6 +385,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) //pNtk = Wlc_NtkAbstractNodes( pNtk, NULL ); //Wlc_AbcUpdateNtk( pAbc, pNtk ); //Wlc_GenerateSmtStdout( pAbc ); + Wlc_NtkSimulateTest( (Wlc_Ntk_t *)pAbc->pAbcWlc ); return 0; usage: Abc_Print( -2, "usage: %%test [-vh]\n" ); diff --git a/src/base/wlc/wlcNtk.c b/src/base/wlc/wlcNtk.c index 1aeae102..44a114f4 100644 --- a/src/base/wlc/wlcNtk.c +++ b/src/base/wlc/wlcNtk.c @@ -212,6 +212,7 @@ void Wlc_NtkFree( Wlc_Ntk_t * p ) ABC_FREE( p->vNameIds.pArray ); ABC_FREE( p->vValues.pArray ); ABC_FREE( p->vCopies.pArray ); + ABC_FREE( p->vBits.pArray ); ABC_FREE( p->pInits ); ABC_FREE( p->pObjs ); ABC_FREE( p->pName ); diff --git a/src/base/wlc/wlcSim.c b/src/base/wlc/wlcSim.c new file mode 100644 index 00000000..8b0f041b --- /dev/null +++ b/src/base/wlc/wlcSim.c @@ -0,0 +1,251 @@ +/**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->iPatsPi * 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->iPatsPi; 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->iPatsPi; 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->iPatsPi; w++ ) + pSimCo[w] = ~pSimDri[w]; + else + for ( w = 0; w < p->iPatsPi; 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->iPatsPi; w++ ) + pSim[w] = ~pSim0[w] & ~pSim1[w]; + else if ( Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->iPatsPi; w++ ) + pSim[w] = ~pSim0[w] & pSim1[w]; + else if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) + for ( w = 0; w < p->iPatsPi; w++ ) + pSim[w] = pSim0[w] & ~pSim1[w]; + else + for ( w = 0; w < p->iPatsPi; 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->iPatsPi = 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 = 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->iPatsPi = 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 = 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 + -- cgit v1.2.3