diff options
Diffstat (limited to 'src/base/wlc')
-rw-r--r-- | src/base/wlc/wlc.c | 440 | ||||
-rw-r--r-- | src/base/wlc/wlc.h | 2 | ||||
-rw-r--r-- | src/base/wlc/wlcAbc.c | 14 | ||||
-rw-r--r-- | src/base/wlc/wlcAbs.c | 8 | ||||
-rw-r--r-- | src/base/wlc/wlcBlast.c | 120 | ||||
-rw-r--r-- | src/base/wlc/wlcCom.c | 61 | ||||
-rw-r--r-- | src/base/wlc/wlcNdr.c | 15 |
7 files changed, 624 insertions, 36 deletions
diff --git a/src/base/wlc/wlc.c b/src/base/wlc/wlc.c index 6f0890e2..261ec96b 100644 --- a/src/base/wlc/wlc.c +++ b/src/base/wlc/wlc.c @@ -265,6 +265,446 @@ void Wlc_BlastMultiplierCnfTest( int nBits ) sat_solver_delete( pSat ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Vec_Int_t * Wlc_ManGenAdderN( Gia_Man_t * p, int nLits, int * pLitsA, int * pLitsB, int Carry ) +{ + extern void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps ); + Vec_Int_t * vRes = Vec_IntStart( nLits + 1 ); + int i, * pRes = Vec_IntArray(vRes); + for ( i = 0; i < nLits; i++ ) + Wlc_BlastFullAdder( p, pLitsA[i], pLitsB[i], Carry, &Carry, &pRes[i] ); + pRes[nLits] = Carry; + return vRes; +} +Vec_Int_t * Wlc_ManGenAdder2_rec( Gia_Man_t * p, int nLits, int * pLitsA, int * pLitsB, int Carry, int Size ) +{ + Vec_Int_t * vRes, * vRes0, * vRes1, * vRes2; int i, iCtrl; + if ( nLits == Size ) + return Wlc_ManGenAdderN( p, nLits, pLitsA, pLitsB, Carry ); + vRes0 = Wlc_ManGenAdder2_rec( p, nLits/2, pLitsA, pLitsB, Carry, Size ); + vRes1 = Wlc_ManGenAdder2_rec( p, nLits/2, pLitsA + nLits/2, pLitsB + nLits/2, 0, Size ); + vRes2 = Wlc_ManGenAdder2_rec( p, nLits/2, pLitsA + nLits/2, pLitsB + nLits/2, 1, Size ); + vRes = Vec_IntAlloc( nLits + 1 ); + Vec_IntAppend( vRes, vRes0 ); + iCtrl = Vec_IntPop( vRes ); + for ( i = 0; i <= nLits/2; i++ ) + Vec_IntPush( vRes, Gia_ManHashMux(p, iCtrl, Vec_IntEntry(vRes2, i), Vec_IntEntry(vRes1, i)) ); + assert( Vec_IntSize(vRes) == nLits + 1 ); + Vec_IntFree( vRes0 ); + Vec_IntFree( vRes1 ); + Vec_IntFree( vRes2 ); + return vRes; +} +Gia_Man_t * Wlc_ManGenAdder2( int nBits, int Size, int fSigned ) +{ + Gia_Man_t * pTemp, * pNew; int n, i, iLit, nBitsAll; + Vec_Int_t * vOuts, * vLits = Vec_IntAlloc( 1000 ); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "adder" ); + for ( nBitsAll = Size; nBitsAll < nBits; nBitsAll *= 2 ) + ; + for ( n = 0; n < 2; n++ ) + { + for ( i = 0; i < nBits; i++ ) + Vec_IntPush( vLits, Gia_ManAppendCi(pNew) ); + for ( ; i < nBitsAll; i++ ) + Vec_IntPush( vLits, fSigned ? Vec_IntEntry(vLits, nBits-1) : 0 ); + } + Gia_ManHashAlloc( pNew ); + vOuts = Wlc_ManGenAdder2_rec( pNew, nBitsAll, Vec_IntEntryP(vLits, 0), Vec_IntEntryP(vLits, Vec_IntSize(vLits)/2), 0, Size ); + Gia_ManHashStop( pNew ); + Vec_IntForEachEntry( vOuts, iLit, i ) + Gia_ManAppendCo( pNew, iLit ); + Vec_IntFree( vLits ); + Vec_IntFree( vOuts ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +Vec_Int_t * Wlc_ManGenAdder_rec( Gia_Man_t * p, int nLits, int * pLitsA, int * pLitsB, int Carry, int Size ) +{ + Vec_Int_t * vRes, * vRes0, * vRes1, * vRes2, * vRes3, * vRes4; int i, iCtrl; + if ( nLits == Size ) + return Wlc_ManGenAdderN( p, nLits, pLitsA, pLitsB, Carry ); + assert( nLits % 3 == 0 ); + vRes0 = Wlc_ManGenAdder_rec( p, nLits/3, pLitsA + 0*nLits/3, pLitsB + 0*nLits/3, Carry, Size ); + vRes1 = Wlc_ManGenAdder_rec( p, nLits/3, pLitsA + 1*nLits/3, pLitsB + 1*nLits/3, 0, Size ); + vRes2 = Wlc_ManGenAdder_rec( p, nLits/3, pLitsA + 1*nLits/3, pLitsB + 1*nLits/3, 1, Size ); + vRes3 = Wlc_ManGenAdder_rec( p, nLits/3, pLitsA + 2*nLits/3, pLitsB + 2*nLits/3, 0, Size ); + vRes4 = Wlc_ManGenAdder_rec( p, nLits/3, pLitsA + 2*nLits/3, pLitsB + 2*nLits/3, 1, Size ); + vRes = Vec_IntAlloc( nLits + 1 ); + Vec_IntAppend( vRes, vRes0 ); + iCtrl = Vec_IntPop( vRes ); + for ( i = 0; i <= nLits/3; i++ ) + Vec_IntPush( vRes, Gia_ManHashMux(p, iCtrl, Vec_IntEntry(vRes2, i), Vec_IntEntry(vRes1, i)) ); + iCtrl = Vec_IntPop( vRes ); + for ( i = 0; i <= nLits/3; i++ ) + Vec_IntPush( vRes, Gia_ManHashMux(p, iCtrl, Vec_IntEntry(vRes4, i), Vec_IntEntry(vRes3, i)) ); + assert( Vec_IntSize(vRes) == nLits + 1 ); + Vec_IntFree( vRes0 ); + Vec_IntFree( vRes1 ); + Vec_IntFree( vRes2 ); + Vec_IntFree( vRes3 ); + Vec_IntFree( vRes4 ); + return vRes; +} +Gia_Man_t * Wlc_ManGenAdder( int nBits ) +{ + Gia_Man_t * pTemp, * pNew; int n, i, iLit, nBitsAll; + Vec_Int_t * vOuts, * vLits = Vec_IntAlloc( 1000 ); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "adder" ); + for ( nBitsAll = 3; nBitsAll < nBits; nBitsAll *= 3 ) + ; + for ( n = 0; n < 2; n++ ) + { + for ( i = 0; i < nBits; i++ ) + Vec_IntPush( vLits, Gia_ManAppendCi(pNew) ); + for ( ; i < nBitsAll; i++ ) + Vec_IntPush( vLits, 0 ); + } + Gia_ManHashAlloc( pNew ); + vOuts = Wlc_ManGenAdder_rec( pNew, nBitsAll, Vec_IntEntryP(vLits, 0), Vec_IntEntryP(vLits, Vec_IntSize(vLits)/2), 0, 3 ); + Gia_ManHashStop( pNew ); + Vec_IntForEachEntryStop( vOuts, iLit, i, nBits+1 ) + Gia_ManAppendCo( pNew, iLit ); + Vec_IntFree( vLits ); + Vec_IntFree( vOuts ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Wlc_BuildOne32( Gia_Man_t * p, int * pLitIn, int * pLitOut ) +{ + Wlc_BlastFullAdder( p, pLitIn[0], pLitIn[1], pLitIn[2], &pLitIn[5], &pLitOut[0] ); + Wlc_BlastFullAdder( p, pLitIn[3], pLitIn[4], pLitIn[5], &pLitOut[2], &pLitOut[1] ); +} +void Wlc_BuildOne51( Gia_Man_t * p, int * pLitIn, int * pLitOut ) +{ + int Lit00, Lit01, Lit11; + Wlc_BlastFullAdder( p, pLitIn[0], pLitIn[1], pLitIn[2], &Lit01, &Lit00 ); + Wlc_BlastFullAdder( p, pLitIn[3], pLitIn[4], Lit00, &Lit11, &pLitOut[0] ); + Wlc_BlastFullAdder( p, pLitIn[5], Lit01, Lit11, &pLitOut[2], &pLitOut[1] ); +} +void Wlc_BuildOne6( Gia_Man_t * p, int * pLitIn, int Const1, int * pLitOut ) +{ + int Lit00, Lit01, Lit10, Lit11, Lit12; + Wlc_BlastFullAdder( p, pLitIn[0], pLitIn[1], pLitIn[2], &Lit01, &Lit00 ); + Wlc_BlastFullAdder( p, pLitIn[3], pLitIn[4], pLitIn[5], &Lit11, &Lit10 ); + Wlc_BlastFullAdder( p, Lit00, Lit10, Const1, &Lit12, &pLitOut[0] ); + Wlc_BlastFullAdder( p, Lit01, Lit11, Lit12, &pLitOut[2],&pLitOut[1] ); +} +Vec_Wec_t * Wlc_ManGenTree_iter( Gia_Man_t * p, Vec_Wec_t * vBits, int * pCounter ) +{ + Vec_Wec_t * vBitsNew = Vec_WecStart( Vec_WecSize(vBits) ); + int i, k, pLitsIn[16], pLitsOut[16], Count = 0, fSimple = Vec_WecMaxLevelSize(vBits) <= 3; + for ( i = 0; i < Vec_WecSize(vBits)-1; i++ ) + { + Vec_Int_t * vBits0 = Vec_WecEntry(vBits, i); + Vec_Int_t * vBits1 = Vec_WecEntry(vBits, i+1); + if ( fSimple ) + { + assert( Vec_IntSize(vBits0) <= 3 ); + for ( k = 0; Vec_IntSize(vBits0) > 0; k++ ) + pLitsIn[k] = Vec_IntPop( vBits0 ); + for ( ; k < 3; k++ ) + pLitsIn[k] = 0; + assert( k == 3 ); + Wlc_BlastFullAdder( p, pLitsIn[0], pLitsIn[1], pLitsIn[2], &pLitsOut[1], &pLitsOut[0] ); + Vec_WecPush( vBitsNew, i+0, pLitsOut[0] ); + Vec_WecPush( vBitsNew, i+1, pLitsOut[1] ); + Count += 2; + continue; + } + while ( Vec_IntSize(vBits0) >= 6 ) + { + for ( k = 0; k < 6; k++ ) + pLitsIn[k] = Vec_IntPop( vBits0 ); + assert( k == 6 ); + Wlc_BuildOne6( p, pLitsIn, 0, pLitsOut ); + Vec_WecPush( vBitsNew, i+0, pLitsOut[0] ); + Vec_WecPush( vBitsNew, i+1, pLitsOut[1] ); + Vec_WecPush( vBitsNew, i+2, pLitsOut[2] ); + Count += 3; + } + if ( Vec_IntSize(vBits0) == 5 && Vec_IntSize(vBits1) > 0 ) + { + for ( k = 0; Vec_IntSize(vBits0) > 0; k++ ) + pLitsIn[k] = Vec_IntPop( vBits0 ); + pLitsIn[k++] = Vec_IntPop( vBits1 ); + assert( k == 6 ); + Wlc_BuildOne51( p, pLitsIn, pLitsOut ); + Vec_WecPush( vBitsNew, i+0, pLitsOut[0] ); + Vec_WecPush( vBitsNew, i+1, pLitsOut[1] ); + Vec_WecPush( vBitsNew, i+2, pLitsOut[2] ); + Count += 3; + } + if ( Vec_IntSize(vBits0) == 5 && Vec_IntSize(vBits1) == 0 ) + { + for ( k = 0; Vec_IntSize(vBits0) > 0; k++ ) + pLitsIn[k] = Vec_IntPop( vBits0 ); + pLitsIn[k++] = 0; + assert( k == 6 ); + Wlc_BuildOne6( p, pLitsIn, 0, pLitsOut ); + Vec_WecPush( vBitsNew, i+0, pLitsOut[0] ); + Vec_WecPush( vBitsNew, i+1, pLitsOut[1] ); + Vec_WecPush( vBitsNew, i+2, pLitsOut[2] ); + Count += 3; + } + if ( Vec_IntSize(vBits0) == 4 && Vec_IntSize(vBits1) > 0 ) + { + for ( k = 0; Vec_IntSize(vBits0) > 0; k++ ) + pLitsIn[k] = Vec_IntPop( vBits0 ); + pLitsIn[k++] = 0; + pLitsIn[k++] = Vec_IntPop( vBits1 ); + assert( k == 6 ); + Wlc_BuildOne51( p, pLitsIn, pLitsOut ); + Vec_WecPush( vBitsNew, i+0, pLitsOut[0] ); + Vec_WecPush( vBitsNew, i+1, pLitsOut[1] ); + Vec_WecPush( vBitsNew, i+2, pLitsOut[2] ); + Count += 3; + } + if ( Vec_IntSize(vBits0) == 3 && Vec_IntSize(vBits1) >= 2 ) + { + for ( k = 0; Vec_IntSize(vBits0) > 0; k++ ) + pLitsIn[k] = Vec_IntPop( vBits0 ); + pLitsIn[k++] = Vec_IntPop( vBits1 ); + pLitsIn[k++] = Vec_IntPop( vBits1 ); + assert( k == 5 ); + Wlc_BuildOne32( p, pLitsIn, pLitsOut ); + Vec_WecPush( vBitsNew, i+0, pLitsOut[0] ); + Vec_WecPush( vBitsNew, i+1, pLitsOut[1] ); + Vec_WecPush( vBitsNew, i+2, pLitsOut[2] ); + Count += 3; + } + if ( Vec_IntSize(vBits0) >= 3 ) + { + for ( k = 0; k < 3; k++ ) + pLitsIn[k] = Vec_IntPop( vBits0 ); + assert( k == 3 ); + Wlc_BlastFullAdder( p, pLitsIn[0], pLitsIn[1], pLitsIn[2], &pLitsOut[1], &pLitsOut[0] ); + Vec_WecPush( vBitsNew, i+0, pLitsOut[0] ); + Vec_WecPush( vBitsNew, i+1, pLitsOut[1] ); + Count += 2; + } +/* + if ( Vec_IntSize(vBits0) == 2 ) + { + Vec_IntClear( vBits0 ); + Vec_WecPush( vBitsNew, i+0, 0 ); + Vec_WecPush( vBitsNew, i+1, 0 ); + Count += 2; + } +*/ + for ( k = 0; Vec_IntSize(vBits0) > 0; k++ ) + Vec_WecPush( vBitsNew, i, Vec_IntPop(vBits0) ); + } + if ( pCounter ) + *pCounter = Count; + return vBitsNew; +} +void Wlc_ManGenTreeOne( Gia_Man_t * pNew, Vec_Wec_t * vBits0, int fMult, int fVerbose ) +{ + extern int Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ); // result is in pAdd0 + + Vec_Wec_t * vTemp, * vBits = Vec_WecDup( vBits0 ); + Vec_Int_t * vOuts = Vec_IntAlloc( 1000 ), * vOuts2; + Vec_Int_t * vLits0 = Vec_IntAlloc( 1000 ); + Vec_Int_t * vLits1 = Vec_IntAlloc( 1000 ); + int i, iLit, nBitsAll = 0, CounterAll = 0, Counter = 1; + for ( i = 0; Counter && i < 1000; i++ ) + { + if ( fVerbose ) printf( "LEVEL %d\n", i ); + if ( fVerbose ) Vec_WecPrint( vBits, 0 ); + if ( Vec_WecMaxLevelSize(vBits) <= 2 ) + break; + vBits = Wlc_ManGenTree_iter( pNew, vTemp = vBits, &Counter ); + Vec_WecFree( vTemp ); + CounterAll += Counter; + } + printf( "Total count = %d.\n", CounterAll ); + if ( !fMult ) + { + int Carry; +/* + Vec_WecForEachLevel( vBits, vOuts2, i ) + { + if ( i == 10 ) + break; + if ( i == 0 ) + { + assert( Vec_IntSize(vOuts2) == 1 ); + Vec_IntPush( vOuts, Vec_IntPop(vOuts2) ); + continue; + } + assert( Vec_IntSize(vOuts2) == 1 || Vec_IntSize(vOuts2) == 2 ); + Vec_IntPush( vLits0, Vec_IntPop(vOuts2) ); + if ( Vec_IntSize(vOuts2) == 1 ) + Vec_IntPush( vLits1, Vec_IntPop(vOuts2) ); + else + { + Vec_IntPush( vLits1, 0 ); + } + } + assert( Vec_IntSize(vLits0) == 9 ); + assert( Vec_IntSize(vLits1) == 9 ); +*/ + Vec_WecForEachLevel( vBits, vOuts2, i ) + { + if ( Vec_IntSize(vOuts2) == 0 ) + break; + assert( Vec_IntSize(vOuts2) == 1 || Vec_IntSize(vOuts2) == 2 ); + Vec_IntPush( vLits0, Vec_IntPop(vOuts2) ); + if ( Vec_IntSize(vOuts2) == 1 ) + Vec_IntPush( vLits1, Vec_IntPop(vOuts2) ); + else + Vec_IntPush( vLits1, 0 ); + } + printf( "The adder size is %d.\n", Vec_IntSize(vLits0) ); + Vec_IntShrink( vLits0, 11 ); + Vec_IntShrink( vLits1, 11 ); + +// vOuts2 = Wlc_ManGenAdder_rec( pNew, 9, Vec_IntArray(vLits0), Vec_IntArray(vLits1), 0, 3 ); +// Vec_IntAppend( vOuts, vOuts2 ); +// Vec_IntFree( vOuts2 ); + + Carry = Wlc_BlastAdder( pNew, Vec_IntArray(vLits0), Vec_IntArray(vLits1), 11, 0 ); + Vec_IntAppend( vOuts, vLits0 ); + Vec_IntPush( vOuts, Carry ); + + + Gia_ManAppendCo( pNew, Vec_IntEntry(vOuts, 11) ); + } + else + { + Vec_WecForEachLevel( vBits, vOuts2, i ) + { + if ( Vec_IntSize(vOuts2) == 0 ) + break; + assert( Vec_IntSize(vOuts2) == 1 || Vec_IntSize(vOuts2) == 2 ); + Vec_IntPush( vLits0, Vec_IntPop(vOuts2) ); + if ( Vec_IntSize(vOuts2) == 1 ) + Vec_IntPush( vLits1, Vec_IntPop(vOuts2) ); + else + Vec_IntPush( vLits1, 0 ); + } + printf( "The adder size is %d.\n", Vec_IntSize(vLits0) ); + Vec_IntShrink( vLits0, Gia_ManCiNum(pNew)+1 ); // mult + Vec_IntShrink( vLits1, Gia_ManCiNum(pNew)+1 ); // mult + + for ( nBitsAll = 3; nBitsAll < Vec_IntSize(vLits0); nBitsAll *= 3 ) + ; + for ( i = Vec_IntSize(vLits0); i < nBitsAll; i++ ) + { + Vec_IntPush( vLits0, 0 ); + Vec_IntPush( vLits1, 0 ); + } + assert( Vec_IntSize(vLits0) == nBitsAll ); + assert( Vec_IntSize(vLits1) == nBitsAll ); + + vOuts2 = Wlc_ManGenAdder_rec( pNew, nBitsAll, Vec_IntArray(vLits0), Vec_IntArray(vLits1), 0, 3 ); + Vec_IntAppend( vOuts, vOuts2 ); + Vec_IntFree( vOuts2 ); + //Carry = Wlc_BlastAdder( pNew, Vec_IntArray(vLits0), Vec_IntArray(vLits1), nBitsAll, 0 ); + //Vec_IntAppend( vOuts, vLits0 ); + //Vec_IntPush( vOuts, Carry ); + + Vec_IntShrink( vOuts, Gia_ManCiNum(pNew) ); // mult + //Vec_IntShrink( vOuts, Gia_ManCiNum(pNew)/2 ); + + Vec_IntForEachEntry( vOuts, iLit, i ) + Gia_ManAppendCo( pNew, iLit ); + } + + Vec_IntFree( vOuts ); + Vec_IntFree( vLits0 ); + Vec_IntFree( vLits1 ); + Vec_WecFree( vBits ); +} +Gia_Man_t * Wlc_ManGenTree( int nInputs, int Value, int nBits, int fVerbose ) +{ + Gia_Man_t * pTemp, * pNew; int i, Counter = 0; + Vec_Wec_t * vBits = Vec_WecStart( nBits+2 ); + for ( i = 0; i < nBits+2; i++ ) + Vec_WecPush( vBits, i, (Value >> i) & 1 ); + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "tree" ); + for ( i = 0; i < nInputs; i++ ) + Vec_WecPush( vBits, 0, Gia_ManAppendCi(pNew) ); + Gia_ManHashAlloc( pNew ); + Wlc_ManGenTreeOne( pNew, vBits, 0, fVerbose ); + Gia_ManHashStop( pNew ); + Vec_WecFree( vBits ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Wlc_ManGenProd( int nInputs, int fVerbose ) +{ + extern void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds ); + extern void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds ); + Vec_Int_t * vIns = Vec_IntAlloc( 2*nInputs ); + Gia_Man_t * pTemp, * pNew; + Vec_Wec_t * vProds; int i; + pNew = Gia_ManStart( 1000 ); + pNew->pName = Abc_UtilStrsav( "tree" ); + + for ( i = 0; i < 2*nInputs; i++ ) + Vec_IntPush( vIns, Gia_ManAppendCi(pNew) ); + //for ( i = 0; i < nInputs; i++ ) + // Vec_IntPush( vIns, Gia_ManAppendCi(pNew) ); + //for ( i = 0; i < nInputs; i++ ) + // Vec_IntPush( vIns, Vec_IntEntry(vIns, i) ); + + Gia_ManHashAlloc( pNew ); + Wlc_BlastBooth( pNew, Vec_IntArray(vIns), Vec_IntArray(vIns)+nInputs, nInputs, nInputs, NULL, 0, 0, &vProds ); + //Wlc_BlastMultiplier3( pNew, Vec_IntArray(vIns), Vec_IntArray(vIns)+nInputs, nInputs, nInputs, NULL, 0, 0, &vProds ); + //Vec_WecPrint( vProds, 0 ); + Wlc_ManGenTreeOne( pNew, vProds, 1, fVerbose ); + Gia_ManHashStop( pNew ); + Vec_WecFree( vProds ); + Vec_IntFree( vIns ); + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlc.h b/src/base/wlc/wlc.h index 0a4f745c..0b3bed6c 100644 --- a/src/base/wlc/wlc.h +++ b/src/base/wlc/wlc.h @@ -217,6 +217,7 @@ struct Wlc_BstPar_t_ int fBooth; int fNonRest; int fCla; + int fDivBy0; int fNoCleanup; int fCreateMiter; int fCreateWordMiter; @@ -238,6 +239,7 @@ static inline void Wlc_BstParDefault( Wlc_BstPar_t * pPar ) pPar->fMulti = 0; pPar->fBooth = 0; pPar->fCla = 0; + pPar->fDivBy0 = 0; pPar->fCreateMiter = 0; pPar->fCreateWordMiter = 0; pPar->fDecMuxes = 0; diff --git a/src/base/wlc/wlcAbc.c b/src/base/wlc/wlcAbc.c index e1b06ffd..8b7dbfa7 100644 --- a/src/base/wlc/wlcAbc.c +++ b/src/base/wlc/wlcAbc.c @@ -140,7 +140,7 @@ void Wlc_NtkPrintInvStats( Wlc_Ntk_t * pNtk, Vec_Int_t * vCounts, int fVerbose ) SeeAlso [] ***********************************************************************/ -Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) +Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Ptr_t * vNamesIn ) { extern Vec_Int_t * Pdr_InvCounts( Vec_Int_t * vInv ); extern Vec_Str_t * Pdr_InvPrintStr( Vec_Int_t * vInv, Vec_Int_t * vCounts ); @@ -166,8 +166,16 @@ Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ) if ( Entry == 0 ) continue; pMainObj = Abc_NtkCreatePi( pMainNtk ); - sprintf( Buffer, "pi%d", i ); - Abc_ObjAssignName( pMainObj, Buffer, NULL ); + // If vNamesIn is given, take names from there for as many entries as possible + // otherwise generate names from counter + if (vNamesIn != NULL && i < Vec_PtrSize(vNamesIn)) { + Abc_ObjAssignName( pMainObj, (char *)Vec_PtrEntry(vNamesIn, i), NULL ); + } + else + { + sprintf( Buffer, "pi%d", i ); + Abc_ObjAssignName( pMainObj, Buffer, NULL ); + } } if ( Abc_NtkPiNum(pMainNtk) != nInputs ) { diff --git a/src/base/wlc/wlcAbs.c b/src/base/wlc/wlcAbs.c index 402ce21b..c297c54f 100644 --- a/src/base/wlc/wlcAbs.c +++ b/src/base/wlc/wlcAbs.c @@ -867,10 +867,10 @@ static Vec_Bit_t * Wlc_NtkMarkLimit( Wlc_Ntk_t * p, Wlc_Par_t * pPars ) } } - Vec_PtrSort( vAdds, (int (*)(void))IntPairPtrCompare ) ; - Vec_PtrSort( vMults, (int (*)(void))IntPairPtrCompare ) ; - Vec_PtrSort( vMuxes, (int (*)(void))IntPairPtrCompare ) ; - Vec_PtrSort( vFlops, (int (*)(void))IntPairPtrCompare ) ; + Vec_PtrSort( vAdds, (int (*)(const void *, const void *))IntPairPtrCompare ) ; + Vec_PtrSort( vMults, (int (*)(const void *, const void *))IntPairPtrCompare ) ; + Vec_PtrSort( vMuxes, (int (*)(const void *, const void *))IntPairPtrCompare ) ; + Vec_PtrSort( vFlops, (int (*)(const void *, const void *))IntPairPtrCompare ) ; Vec_PtrForEachEntry( Int_Pair_t *, vAdds, pPair, i ) { diff --git a/src/base/wlc/wlcBlast.c b/src/base/wlc/wlcBlast.c index 3a01e238..6e910cd8 100644 --- a/src/base/wlc/wlcBlast.c +++ b/src/base/wlc/wlcBlast.c @@ -345,11 +345,12 @@ void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * if ( fCompl ) *ps = Abc_LitNot(*ps), *pc = Abc_LitNot(*pc); } -void Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0 +int Wlc_BlastAdder( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0 { int b; for ( b = 0; b < nBits; b++ ) Wlc_BlastFullAdder( pNew, pAdd0[b], pAdd1[b], Carry, &Carry, &pAdd0[b] ); + return Carry; } void Wlc_BlastSubtract( Gia_Man_t * pNew, int * pAdd0, int * pAdd1, int nBits, int Carry ) // result is in pAdd0 { @@ -1022,7 +1023,7 @@ void Wlc_BlastReduceMatrix2( Gia_Man_t * pNew, Vec_Wec_t * vProds, Vec_Int_t * v } -void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla ) +void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds ) { Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB ); Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB ); @@ -1043,7 +1044,10 @@ void Wlc_BlastMultiplier3( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA Vec_WecPush( vLevels, nArgA+nArgB-1, 0 ); } - Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla ); + if ( pvProds ) + *pvProds = Vec_WecDup(vProds); + else + Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla ); // Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla ); Vec_WecFree( vProds ); @@ -1086,7 +1090,7 @@ void Wlc_BlastDecoder( Gia_Man_t * pNew, int * pNum, int nNum, Vec_Int_t * vTmp, Vec_IntPush( vRes, iMint ); } } -void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla ) +void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int nArgB, Vec_Int_t * vRes, int fSigned, int fCla, Vec_Wec_t ** pvProds ) { Vec_Wec_t * vProds = Vec_WecStart( nArgA + nArgB + 3 ); Vec_Wec_t * vLevels = Vec_WecStart( nArgA + nArgB + 3 ); @@ -1159,9 +1163,11 @@ void Wlc_BlastBooth( Gia_Man_t * pNew, int * pArgA, int * pArgB, int nArgA, int //Vec_WecPrint( vProds, 0 ); //Wlc_BlastPrintMatrix( pNew, vProds, 1 ); //printf( "Cutoff ID for partial products = %d.\n", Gia_ManObjNum(pNew) ); - Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla ); -// Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla ); - + if ( pvProds ) + *pvProds = Vec_WecDup(vProds); + else + Wlc_BlastReduceMatrix( pNew, vProds, vLevels, vRes, fSigned, fCla ); + // Wlc_BlastReduceMatrix2( pNew, vProds, vRes, fSigned, fCla ); Vec_WecFree( vProds ); Vec_WecFree( vLevels ); Vec_IntFree( vArgB ); @@ -1792,9 +1798,9 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) if ( Wlc_NtkCountConstBits(pArg0, nRangeMax) < Wlc_NtkCountConstBits(pArg1, nRangeMax) ) ABC_SWAP( int *, pArg0, pArg1 ); if ( pPar->fBooth ) - Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned, pPar->fCla ); + Wlc_BlastBooth( pNew, pArg0, pArg1, nRange0, nRange1, vRes, fSigned, pPar->fCla, NULL ); else if ( pPar->fCla ) - Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla ); + Wlc_BlastMultiplier3( pNew, pArg0, pArg1, nRange0, nRange1, vRes, Wlc_ObjIsSignedFanin01(p, pObj), pPar->fCla, NULL ); else Wlc_BlastMultiplier( pNew, pArg0, pArg1, nRangeMax, nRangeMax, vTemp2, vRes, fSigned ); if ( nRange > Vec_IntSize(vRes) ) @@ -1815,7 +1821,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) else Wlc_BlastDivider( pNew, pArg0, nRangeMax, pArg1, nRangeMax, pObj->Type == WLC_OBJ_ARI_DIVIDE, vRes ); Vec_IntShrink( vRes, nRange ); - //if ( pObj->Type == WLC_OBJ_ARI_DIVIDE ) + if ( !pPar->fDivBy0 ) Wlc_BlastZeroCondition( pNew, pFans1, nRange1, vRes ); } else if ( pObj->Type == WLC_OBJ_ARI_MINUS ) @@ -2104,7 +2110,7 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) // complement flop inputs whose init state is 1 for ( i = 0; i < nFf2Regs; i++ ) Gia_ManAppendCo( pNew, Gia_ManAppendCi(pNew) ); - //Gia_ManSetRegNum( pNew, nFf2Regs ); + Gia_ManSetRegNum( pNew, nFf2Regs ); } else { @@ -2490,6 +2496,98 @@ Gia_Man_t * Wlc_NtkBitBlast( Wlc_Ntk_t * p, Wlc_BstPar_t * pParIn ) return pNew; } + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +float * Extra_FileReadFloat( FILE * pFile, int * pnFileSize ) +{ + float * pBuffer; + int RetValue, nFileSize; + fseek( pFile, 0, SEEK_END ); + nFileSize = *pnFileSize = ftell( pFile ); + rewind( pFile ); + assert( nFileSize%4 == 0 ); + pBuffer = ABC_CALLOC( float, nFileSize/4 ); + RetValue = fread( pBuffer, nFileSize, 1, pFile ); + return pBuffer; +} +float * Extra_FileReadFloatContents( char * pFileName, int * pnFileSize ) +{ + FILE * pFile; + float * pBuffer; + pFile = fopen( pFileName, "rb" ); + pBuffer = pFile ? Extra_FileReadFloat( pFile, pnFileSize ) : NULL; + if ( pFile ) fclose( pFile ); + return pBuffer; +} +static inline int Extra_FixedFound( int Value, int Fixed ) +{ + Value += 1 << (Fixed-1); + Value >>= Fixed; + return Value; +} +static inline int Extra_ConvertFloat8( float Value ) +{ + return Extra_FixedFound( (int)(Value * (1 << 16)), 8 ); +} +Gia_Man_t * Wlc_BlastArray( char * pFileName ) +{ + int nFileSize = 0; + float * pBuffer = Extra_FileReadFloatContents( pFileName, &nFileSize ); + int i, v, Value, nInputs = nFileSize/4 - 1; + Vec_Int_t * vArg0 = Vec_IntAlloc( 100 ); + Vec_Int_t * vArg1 = Vec_IntAlloc( 100 ); + Vec_Int_t * vTemp = Vec_IntAlloc( 100 ); + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + Vec_Int_t * vSum = Vec_IntAlloc( 100 ); + Gia_Man_t * pTemp, * pNew = Gia_ManStart( 10000 ); + pNew->pName = Abc_UtilStrsav( "blast" ); + Gia_ManHashAlloc( pNew ); + for ( i = 0; i < 8*nInputs; i++ ) + Gia_ManAppendCi(pNew); + + Value = (Extra_ConvertFloat8(pBuffer[0]) << 8) | (1 << 7); + for ( v = 0; v < 20; v++ ) + Vec_IntPush( vSum, (Value >> v) & 1 ); + + for ( i = 0; i < nInputs; i++ ) + { + Value = Extra_ConvertFloat8( pBuffer[1+i] ); + + Vec_IntClear( vArg0 ); + for ( v = 0; v < 8; v++ ) + Vec_IntPush( vArg0, Gia_ManCiLit(pNew, 8*i+v) ); + + Vec_IntClear( vArg1 ); + for ( v = 0; v < 12; v++ ) + Vec_IntPush( vArg1, (Value >> v) & 1 ); + + Wlc_BlastMultiplier( pNew, Vec_IntArray(vArg0), Vec_IntArray(vArg1), 8, 12, vTemp, vRes, 1 ); + Wlc_BlastAdder( pNew, Vec_IntArray(vSum), Vec_IntArray(vRes), 20, 0 ); + } + ABC_FREE( pBuffer ); + for ( v = 8; v < 16; v++ ) + Gia_ManAppendCo( pNew, Vec_IntEntry(vSum, v) ); + Vec_IntFree( vArg0 ); + Vec_IntFree( vArg1 ); + Vec_IntFree( vTemp ); + Vec_IntFree( vRes ); + Vec_IntFree( vSum ); + + pNew = Gia_ManCleanup( pTemp = pNew ); + Gia_ManStop( pTemp ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/wlc/wlcCom.c b/src/base/wlc/wlcCom.c index 51f15597..39f1bebd 100644 --- a/src/base/wlc/wlcCom.c +++ b/src/base/wlc/wlcCom.c @@ -1037,7 +1037,7 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) Wlc_BstParDefault( pPar ); pPar->nOutputRange = 2; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombqadestnizvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "ORAMcombqaydestnizvh" ) ) != EOF ) { switch ( c ) { @@ -1103,6 +1103,9 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) case 'a': pPar->fCla ^= 1; break; + case 'y': + pPar->fDivBy0 ^= 1; + break; case 'd': pPar->fCreateMiter ^= 1; break; @@ -1198,7 +1201,7 @@ int Abc_CommandBlast( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_FrameUpdateGia( pAbc, pNew ); return 0; usage: - Abc_Print( -2, "usage: %%blast [-ORAM num] [-combqadestnizvh]\n" ); + Abc_Print( -2, "usage: %%blast [-ORAM num] [-combqaydestnizvh]\n" ); Abc_Print( -2, "\t performs bit-blasting of the word-level design\n" ); Abc_Print( -2, "\t-O num : zero-based index of the first word-level PO to bit-blast [default = %d]\n", pPar->iOutput ); Abc_Print( -2, "\t-R num : the total number of word-level POs to bit-blast [default = %d]\n", pPar->nOutputRange ); @@ -1210,6 +1213,7 @@ usage: Abc_Print( -2, "\t-b : toggle generating radix-4 Booth multipliers [default = %s]\n", pPar->fBooth? "yes": "no" ); Abc_Print( -2, "\t-q : toggle generating non-restoring square root [default = %s]\n", pPar->fNonRest? "yes": "no" ); Abc_Print( -2, "\t-a : toggle generating carry-look-ahead adder [default = %s]\n", pPar->fCla? "yes": "no" ); + Abc_Print( -2, "\t-y : toggle creating different divide-by-0 condition [default = %s]\n", pPar->fDivBy0? "yes": "no" ); Abc_Print( -2, "\t-d : toggle creating dual-output multi-output miter [default = %s]\n", pPar->fCreateMiter? "yes": "no" ); Abc_Print( -2, "\t-e : toggle creating miter with output word bits combined [default = %s]\n", pPar->fCreateWordMiter? "yes": "no" ); Abc_Print( -2, "\t-s : toggle creating decoded MUXes [default = %s]\n", pPar->fDecMuxes? "yes": "no" ); @@ -1327,16 +1331,20 @@ usage: ******************************************************************************/ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern void Wln_NtkRetimeTest( char * pFileName, int fSkipSimple, int fDump, int fVerbose ); + extern void Wln_NtkRetimeTest( char * pFileName, int fIgnoreIO, int fSkipSimple, int fDump, int fVerbose ); FILE * pFile; char * pFileName = NULL; + int fIgnoreIO = 0; int fSkipSimple = 0; int c, fDump = 0, fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "sdvh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "isdvh" ) ) != EOF ) { switch ( c ) { + case 'i': + fIgnoreIO ^= 1; + break; case 's': fSkipSimple ^= 1; break; @@ -1362,7 +1370,7 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) printf( "Transforming NDR into internal represnetation has failed.\n" ); return 0; } - vMoves = Wln_NtkRetime( pNtk, fSkipSimple, fVerbose ); + vMoves = Wln_NtkRetime( pNtk, fIgnoreIO, fSkipSimple, fVerbose ); Wln_NtkFree( pNtk ); ABC_FREE( pAbc->pNdrArray ); if ( vMoves ) pAbc->pNdrArray = Vec_IntReleaseNewArray( vMoves ); @@ -1385,11 +1393,12 @@ int Abc_CommandRetime( Abc_Frame_t * pAbc, int argc, char ** argv ) return 0; } fclose( pFile ); - Wln_NtkRetimeTest( pFileName, fSkipSimple, fDump, fVerbose ); + Wln_NtkRetimeTest( pFileName, fIgnoreIO, fSkipSimple, fDump, fVerbose ); return 0; usage: - Abc_Print( -2, "usage: %%retime [-sdvh]\n" ); + Abc_Print( -2, "usage: %%retime [-isdvh]\n" ); Abc_Print( -2, "\t performs retiming for the NDR design\n" ); + Abc_Print( -2, "\t-i : toggle ignoring delays of IO paths [default = %s]\n", fIgnoreIO? "yes": "no" ); Abc_Print( -2, "\t-s : toggle printing simple nodes [default = %s]\n", !fSkipSimple? "yes": "no" ); Abc_Print( -2, "\t-d : toggle dumping the network in Verilog [default = %s]\n", fDump? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); @@ -1718,15 +1727,19 @@ usage: ******************************************************************************/ int Abc_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv ) { - extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv ); + extern Abc_Ntk_t * Wlc_NtkGetInv( Wlc_Ntk_t * pNtk, Vec_Int_t * vInv, Vec_Ptr_t * vNamesIn ); Abc_Ntk_t * pMainNtk; Wlc_Ntk_t * pNtk = Wlc_AbcGetNtk(pAbc); - int c, fVerbose = 0; + int c, i, fVerbose = 0, fFlopNamesFromGia = 0; + Vec_Ptr_t * vNamesIn = NULL; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "fvh" ) ) != EOF ) { switch ( c ) { + case 'f': + fFlopNamesFromGia ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -1741,16 +1754,38 @@ int Abc_CommandInvGet( Abc_Frame_t * pAbc, int argc, char ** argv ) Abc_Print( 1, "Abc_CommandInvGet(): Invariant is not available.\n" ); return 0; } + // See if we shall and can copy the PI names from the current GIA + if ( fFlopNamesFromGia ) + { + if ( pAbc->pGia == NULL ) + { + Abc_Print( 1, "Abc_CommandInvGet(): No network in &-space, cannot copy names.\n" ); + fFlopNamesFromGia = 0; + } + else + { + vNamesIn = Vec_PtrStart( Gia_ManRegNum(pAbc->pGia) ); + for ( i = 0; i < Gia_ManRegNum(pAbc->pGia); ++i ) + { + // Only the registers + Vec_PtrSetEntry( vNamesIn, i, Extra_UtilStrsav( (const char*)Vec_PtrEntry( pAbc->pGia->vNamesIn, Gia_ManPiNum(pAbc->pGia)+i ) ) ); + } + } + } // derive the network - pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc) ); + pMainNtk = Wlc_NtkGetInv( pNtk, Wlc_AbcGetInv(pAbc), vNamesIn ); + // Delete names + if (vNamesIn) + Vec_PtrFree( vNamesIn ); // replace the current network if ( pMainNtk ) Abc_FrameReplaceCurrentNetwork( pAbc, pMainNtk ); return 0; usage: - Abc_Print( -2, "usage: inv_get [-vh]\n" ); + Abc_Print( -2, "usage: inv_get [-fvh]\n" ); Abc_Print( -2, "\t places invariant found by PDR as the current network in the main-space\n" ); - Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', inifity clauses are used)\n" ); + Abc_Print( -2, "\t (in the case of \'sat\' or \'undecided\', infinity clauses are used)\n" ); + Abc_Print( -2, "\t-f : toggle reading flop names from the &-space [default = %s]\n", fFlopNamesFromGia? "yes": "no" ); Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); Abc_Print( -2, "\t-h : print the command usage\n"); return 1; diff --git a/src/base/wlc/wlcNdr.c b/src/base/wlc/wlcNdr.c index 3212500f..d401281a 100644 --- a/src/base/wlc/wlcNdr.c +++ b/src/base/wlc/wlcNdr.c @@ -263,7 +263,7 @@ void Wlc_NtkToNdrTest( Wlc_Ntk_t * pNtk ) ppNames[i] = Wlc_ObjName(pNtk, i); // verify by writing Verilog - Ndr_WriteVerilog( NULL, pDesign, ppNames ); + Ndr_WriteVerilog( NULL, pDesign, ppNames, 0 ); Ndr_Write( "test.ndr", pDesign ); // cleanup @@ -368,7 +368,7 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) Ndr_Data_t * p = (Ndr_Data_t *)pData; Wlc_Obj_t * pObj; Vec_Int_t * vName2Obj, * vFanins = Vec_IntAlloc( 100 ); int Mod = 2, i, k, Obj, * pArray, nDigits, fFound, NameId, NameIdMax; - Vec_Wrd_t * vTruths = NULL; + Vec_Wrd_t * vTruths = NULL; int nTruths[2] = {0}; Wlc_Ntk_t * pTemp, * pNtk = Wlc_NtkAlloc( "top", Ndr_DataObjNum(p, Mod)+1 ); Wlc_NtkCheckIntegrity( pData ); Vec_IntClear( &pNtk->vFfs ); @@ -415,11 +415,14 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) Vec_IntPush( &pNtk->vFfs2, iObj ); if ( Type == ABC_OPER_LUT ) { + word * pTruth; if ( vTruths == NULL ) vTruths = Vec_WrdStart( 1000 ); if ( NameId >= Vec_WrdSize(vTruths) ) Vec_WrdFillExtra( vTruths, 2*NameId, 0 ); - Vec_WrdWriteEntry( vTruths, NameId, *((word *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION)) ); + pTruth = (word *)Ndr_ObjReadBodyP(p, Obj, NDR_FUNCTION); + Vec_WrdWriteEntry( vTruths, NameId, pTruth ? *pTruth : 0 ); + nTruths[ pTruth != NULL ]++; } if ( Type == ABC_OPER_SLICE ) Vec_IntPushTwo( vFanins, End, Beg ); @@ -437,6 +440,8 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) Wlc_ObjFanin1(pNtk, pObj)->Signed = 1; } } + if ( nTruths[0] ) + printf( "Warning! The number of LUTs without function is %d (out of %d).\n", nTruths[0], nTruths[0]+nTruths[1] ); // mark primary outputs Ndr_ModForEachPo( p, Mod, Obj ) { @@ -487,7 +492,7 @@ Wlc_Ntk_t * Wlc_NtkFromNdr( void * pData ) pNtk->pManName = Abc_NamStart( NameIdMax+1, 10 ); for ( i = 1; i <= NameIdMax; i++ ) { - char pName[20]; sprintf( pName, "s%0*d", nDigits, i ); + char pName[100]; sprintf( pName, "s%0*d", nDigits, i ); NameId = Abc_NamStrFindOrAdd( pNtk->pManName, pName, &fFound ); assert( !fFound && i == NameId ); } @@ -535,7 +540,7 @@ Wlc_Ntk_t * Wlc_ReadNdr( char * pFileName ) void * pData = Ndr_Read( pFileName ); Wlc_Ntk_t * pNtk = Wlc_NtkFromNdr( pData ); //char * ppNames[10] = { NULL, "a", "b", "c", "d", "e", "f", "g", "h", "i" }; - //Ndr_WriteVerilog( NULL, pData, ppNames ); + //Ndr_WriteVerilog( NULL, pData, ppNames, 0 ); //Ndr_Delete( pData ); Abc_FrameInputNdr( Abc_FrameGetGlobalFrame(), pData ); return pNtk; |