From 7285f1051ee21f6c280cc3f67b86184a62bdfb38 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 28 Mar 2017 23:28:04 -0700 Subject: Experiments with multipliers. --- src/base/wlc/wlcGraft.c | 127 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 98 insertions(+), 29 deletions(-) (limited to 'src/base/wlc') diff --git a/src/base/wlc/wlcGraft.c b/src/base/wlc/wlcGraft.c index f7e59cf9..6f95a7be 100644 --- a/src/base/wlc/wlcGraft.c +++ b/src/base/wlc/wlcGraft.c @@ -307,28 +307,31 @@ void Sbc_Mult( word a, word b, word r[2] ) word pM2 = (a >> 32) * (b & 0xFFFFFFFF); word pH = (a >> 32) * (b >> 32); word Car = (pM1 & 0xFFFFFFFF) + (pM2 & 0xFFFFFFFF) + (pL >> 32); - r[0] = pL; + r[0] = a * b; r[1] = pH + (pM1 >> 32) + (pM2 >> 32) + (Car >> 32); } -void Sbc_SimMult( word A[64], word B[64], word R[64][2] ) +void Sbc_SimMult( word A[64], word B[64], word R[128], int nIns ) { - word a, b, r[2]; int i, k; + word a, b, r[2], Mask = Abc_Tt6Mask(nIns); int i, k; for ( i = 0; i < 64; i++ ) - A[i] = B[i] = R[0][i] = R[1][i] = 0; + A[i] = B[i] = R[i] = R[i+64] = 0; Gia_ManRandom(1); for ( i = 0; i < 64; i++ ) { - a = Gia_ManRandom(0); - b = Gia_ManRandom(0); + a = Mask & Gia_ManRandomW(0); + b = Mask & Gia_ManRandomW(0); Sbc_Mult( a, b, r ); for ( k = 0; k < 64; k++ ) { - if ( (a >> k) & 1 ) A[k] |= (1 << i); - if ( (b >> k) & 1 ) B[k] |= (1 << i); - if ( (r[0] >> k) & 1 ) R[0][k] |= (1 << i); - if ( (r[1] >> k) & 1 ) R[1][k] |= (1 << i); + if ( (a >> k) & 1 ) A[k] |= ((word)1 << i); + if ( (b >> k) & 1 ) B[k] |= ((word)1 << i); + if ( (r[0] >> k) & 1 ) R[k] |= ((word)1 << i); + if ( (r[1] >> k) & 1 ) R[k+64] |= ((word)1 << i); } } +// for ( i = 0; i < 128; i++ ) +// for ( k = 0; k < 64; k++, printf( "\n" ) ) +// printf( "%d", (R[i] >> k) & 1 ); } /**Function************************************************************* @@ -347,31 +350,37 @@ Vec_Int_t * Sbc_ManDetectMult( Gia_Man_t * p, Vec_Int_t * vIns ) int nWords = 1; Vec_Int_t * vNodes = Vec_IntStart( Vec_IntSize(vIns) ); Gia_Obj_t * pObj; int i, Entry, nIns = Vec_IntSize(vIns)/2; - word A[64], B[64], R[64][2], * pInfoObj; + word A[64], B[64], R[128], Z = 0, * pInfoObj; - // alloc simulation info + // create hash table Vec_Mem_t * vTtMem = Vec_MemAlloc( nWords, 10 ); - Vec_MemHashAlloc( vTtMem, 10000 ); + Vec_MemHashAlloc( vTtMem, 1000 ); + Vec_MemHashInsert( vTtMem, &Z ); + Sbc_SimMult( A, B, R, nIns ); + for ( i = 0; i < 2*nIns; i++ ) + Vec_MemHashInsert( vTtMem, R+i ); + assert( Vec_MemEntryNum(vTtMem) == 2*nIns+1 ); + + // alloc simulation info Vec_WrdFreeP( &p->vSims ); p->vSims = Vec_WrdStart( Gia_ManObjNum(p) * nWords ); p->nSimWords = nWords; - // prepare simulation manager - pInfoObj = Wlc_ObjSim( p, 0 ); - Vec_MemHashInsert( vTtMem, pInfoObj ); + // mark inputs + Gia_ManIncrementTravId( p ); Gia_ObjSetTravIdCurrentId( p, 0 ); Gia_ManForEachCi( p, pObj, i ) Gia_ObjSetTravIdCurrent( p, pObj ); - // set internal nodes - assert( Vec_IntSize(vIns) % 2 ); - Sbc_SimMult( A, B, R ); - Gia_ManIncrementTravId( p ); + + // assign inputs + assert( Vec_IntSize(vIns) % 2 == 0 ); Gia_ManForEachObjVec( vIns, p, pObj, i ) { Gia_ObjSetTravIdCurrent( p, pObj ); pInfoObj = Wlc_ObjSim( p, Gia_ObjId(p, pObj) ); - *pInfoObj = i < nIns ? A[i] : B[nIns-i]; + *pInfoObj = i < nIns ? A[i] : B[i - nIns]; } + // perform simulation Gia_ManForEachObj1( p, pObj, i ) { @@ -388,8 +397,8 @@ Vec_Int_t * Sbc_ManDetectMult( Gia_Man_t * p, Vec_Int_t * vIns ) Entry = *Vec_MemHashLookup( vTtMem, pInfoObj ); if ( Entry > 0 ) { - if ( Vec_IntEntry(vNodes, Entry) == 0 ) // new - Vec_IntWriteEntry( vNodes, Entry, Abc_Var2Lit(i, 0) ); + if ( Vec_IntEntry(vNodes, Entry-1) == 0 ) // new + Vec_IntWriteEntry( vNodes, Entry-1, Abc_Var2Lit(i, 0) ); continue; } Abc_TtNot( pInfoObj, nWords ); @@ -397,8 +406,8 @@ Vec_Int_t * Sbc_ManDetectMult( Gia_Man_t * p, Vec_Int_t * vIns ) Abc_TtNot( pInfoObj, nWords ); if ( Entry > 0 ) { - if ( Vec_IntEntry(vNodes, Entry) == 0 ) // new - Vec_IntWriteEntry( vNodes, Entry, Abc_Var2Lit(i, 1) ); + if ( Vec_IntEntry(vNodes, Entry-1) == 0 ) // new + Vec_IntWriteEntry( vNodes, Entry-1, Abc_Var2Lit(i, 1) ); continue; } } @@ -409,6 +418,44 @@ Vec_Int_t * Sbc_ManDetectMult( Gia_Man_t * p, Vec_Int_t * vIns ) p->nSimWords = 0; return vNodes; } +Vec_Int_t * Sbc_ManWlcNodes( Wlc_Ntk_t * pNtk, Gia_Man_t * p, Vec_Int_t * vGiaLits ) +{ + Wlc_Obj_t * pObj; int i, k, iGiaLit, iFirst, nBits; + Vec_Int_t * vRes = Vec_IntAlloc( 100 ); + Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ); + Vec_IntForEachEntry( vGiaLits, iGiaLit, i ) + Vec_IntWriteEntry( vMap, Abc_Lit2Var(iGiaLit), Abc_Var2Lit(i, Abc_LitIsCompl(iGiaLit)) ); + Wlc_NtkForEachObj( pNtk, pObj, i ) + { + iFirst = Vec_IntEntry( &pNtk->vCopies, i ); + nBits = Wlc_ObjRange(pObj); + for ( k = 0; k < nBits; k++ ) + { + int iLitGia = Vec_IntEntry( &pNtk->vBits, iFirst + k ); + int iLitOut = Vec_IntEntry( vMap, Abc_Lit2Var(iLitGia) ); + if ( iLitOut == -1 ) + continue; + Vec_IntWriteEntry( vMap, Abc_Lit2Var(iLitGia), -1 ); + iLitOut = Abc_LitNotCond( iLitOut, Abc_LitIsCompl(iLitGia) ); + printf( "Matched out %d in phase %d with object %d (%s) bit %d (out of %d).\n", Abc_Lit2Var(iLitOut), Abc_LitIsCompl(iLitOut), i, Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)), k, nBits ); + Vec_IntPushUnique( vRes, i ); + } + } + Vec_IntFree( vMap ); + // consider the last one + pObj = Wlc_NtkObj( pNtk, Vec_IntEntryLast(vRes) ); + iFirst = Vec_IntEntry( &pNtk->vCopies, Wlc_ObjId(pNtk, pObj) ); + nBits = Wlc_ObjRange(pObj); + printf( "Considering object %d (%s):\n", Wlc_ObjId(pNtk, pObj), Wlc_ObjName(pNtk, Wlc_ObjId(pNtk, pObj)) ); + for ( k = 0; k < nBits; k++ ) + { + int iLitGia = Vec_IntEntry( &pNtk->vBits, iFirst + k ); + int iLitOutP = Vec_IntFind( vGiaLits, iLitGia ); + int iLitOutN = Vec_IntFind( vGiaLits, Abc_LitNot(iLitGia) ); + printf( "Matching bit %d with output %d / %d.\n", k, iLitOutP, iLitOutN ); + } + return vRes; +} /**Function************************************************************* @@ -421,17 +468,39 @@ Vec_Int_t * Sbc_ManDetectMult( Gia_Man_t * p, Vec_Int_t * vIns ) SeeAlso [] ***********************************************************************/ -void Sbc_ManDetectMultTest( Gia_Man_t * p ) +void Sbc_ManDetectMultTest( Wlc_Ntk_t * pNtk, int fVerbose ) { extern Vec_Int_t * Sdb_StoComputeCutsDetect( Gia_Man_t * pGia ); + Gia_Man_t * p = Wlc_NtkBitBlast( pNtk, NULL, -1, 0, 0, 0, 0, 1 ); + Vec_Int_t * vIns, * vNodes, * vNodesNew; +// Gia_Obj_t * pObj; int i; +// Gia_ManForEachCo( p, pObj, i ) +// printf( "Output %2d - driver %5d (%d)\n", i, Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) ); + + vIns = Sdb_StoComputeCutsDetect( p ); + if ( vIns == NULL || Vec_IntSize(vIns) == 0 || (Vec_IntSize(vIns) % 2) != 0 ) + { + printf( "Input identification did not work out.\n" ); + return; + } - Vec_Int_t * vIns = Sdb_StoComputeCutsDetect( p ); - Vec_Int_t * vNodes = Sbc_ManDetectMult( p, vIns ); - + vNodes = Sbc_ManDetectMult( p, vIns ); + if ( vNodes == NULL || Vec_IntSize(vNodes) == 0 ) + { + printf( "Output identification did not work out.\n" ); + return; + } Vec_IntPrint( vNodes ); + vNodesNew = Sbc_ManWlcNodes( pNtk, p, vNodes ); + + Vec_IntPrint( vNodesNew ); + Vec_IntFree( vNodes ); + Vec_IntFree( vNodesNew ); Vec_IntFree( vIns ); + + Gia_ManStop( p ); } //////////////////////////////////////////////////////////////////////// -- cgit v1.2.3