Commit 7285f105 by Alan Mishchenko

Experiments with multipliers.

parent fdfb8888
......@@ -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 );
}
////////////////////////////////////////////////////////////////////////
......
......@@ -880,7 +880,7 @@ int Sdb_StoDiffExactlyOne2( Vec_Int_t * vAll, int * pCut )
}
Vec_Int_t * Sdb_StoFindInputs( Vec_Wec_t * vCuts, int Front )
{
int fVerbose = 1;
int fVerbose = 0;
Vec_Int_t * vCut, * vCounts;
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
Vec_Int_t * vResA = Vec_IntAlloc( 100 );
......@@ -906,6 +906,8 @@ Vec_Int_t * Sdb_StoFindInputs( Vec_Wec_t * vCuts, int Front )
Vec_IntForEachEntry( vCounts, Entry, k )
if ( Entry )
MinValue = Abc_MinInt( MinValue, Entry );
if ( MinValue == ABC_INFINITY )
return vRes;
Min = Vec_IntFind( vCounts, MinValue );
Vec_IntPush( vResA, Min );
Vec_IntWriteEntry( vCounts, Min, 0 );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment