Experiments with detecting multipliers.

This commit is contained in:
Alan Mishchenko 2024-08-10 19:24:00 -07:00
parent e824cca0ca
commit 807f6ddacf
1 changed files with 433 additions and 30 deletions

View File

@ -31,6 +31,403 @@ ABC_NAMESPACE_IMPL_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManMulFindXors2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXor )
{
if ( !Gia_ObjIsAnd(pObj) )
return;
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return;
Gia_ObjSetTravIdCurrent(p, pObj);
if ( !pObj->fMark0 )
{
if ( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj)
&& Gia_ObjRefNum(p, Gia_ObjFanin0(pObj)) >= 4
&& Gia_ObjRefNum(p, Gia_ObjFanin1(pObj)) >= 4 )
Vec_IntPushTwo( vXor, Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninId1p(p, pObj) );
return;
}
Gia_Obj_t * pFan0, * pFan1;
int RetValue = Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1);
assert( RetValue );
Gia_ManMulFindXors2_rec( p, Gia_Regular(pFan0), vXor );
Gia_ManMulFindXors2_rec( p, Gia_Regular(pFan1), vXor );
}
Vec_Wec_t * Gia_ManMulFindXors2( Gia_Man_t * p )
{
Vec_Wec_t * vXors = Vec_WecAlloc( 100 );
Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
Gia_Obj_t * pObj, * pFan0, * pFan1; int i;
Gia_ManCreateRefs( p );
Gia_ManCleanMark01( p );
Gia_ManForEachAnd( p, pObj, i ) {
if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
continue;
Gia_Regular(pFan0)->fMark1 = 1;
Gia_Regular(pFan1)->fMark1 = 1;
pObj->fMark0 = 1;
}
Gia_ManForEachAnd( p, pObj, i ) {
if ( pObj->fMark0 && !pObj->fMark1 ) {
Gia_ManIncrementTravId( p );
Vec_IntClear( vTemp );
Gia_ManMulFindXors2_rec( p, pObj, vTemp );
if ( Vec_IntSize(vTemp) > 0 )
Vec_IntAppend( Vec_WecPushLevel(vXors), vTemp );
}
}
Vec_IntFree( vTemp );
return vXors;
}
int Gia_ManMulFindMaxSize( Vec_Wec_t * vXors, Vec_Int_t * vUsed )
{
Vec_Int_t * vLevel; int i, iBest = -1, nBestSize = 0;
Vec_WecForEachLevel( vXors, vLevel, i )
if ( !Vec_IntEntry(vUsed, i) && nBestSize < Vec_IntSize(vLevel) )
nBestSize = Vec_IntSize(vLevel), iBest = i;
return iBest;
}
int Gia_ManMulFindGetOverlap( Vec_Int_t * p1, Vec_Int_t * p2 )
{
int i, k, ObjI, ObjK, Counter = 0;
Vec_IntForEachEntry( p1, ObjI, i )
Vec_IntForEachEntry( p2, ObjK, k )
if ( ObjI == ObjK )
Counter++;
return Counter;
}
int Gia_ManMulFindGetOverlap2( Vec_Int_t * p1, Vec_Int_t * p2 )
{
int i, k, ObjI, ObjK, Counter = 0;
Vec_IntForEachEntryStart( p1, ObjI, i, 1 )
Vec_IntForEachEntry( p2, ObjK, k )
if ( ObjI == ObjK )
Counter++;
return Counter;
}
int Gia_ManMulFindMaxOverlap( Vec_Wec_t * vXors, Vec_Int_t * vUsed, Vec_Int_t * vFound )
{
Vec_Int_t * vLevel; int i, iBest = -1, nThisSize, nBestSize = 0;
Vec_WecForEachLevel( vXors, vLevel, i )
if ( !Vec_IntEntry(vUsed, i) && nBestSize < (nThisSize = Gia_ManMulFindGetOverlap(vFound, vLevel)) )
nBestSize = nThisSize, iBest = i;
return iBest;
}
Vec_Wec_t * Gia_ManMulFindSets( Gia_Man_t * p, Vec_Wec_t * vXors )
{
Vec_Wec_t * vSets = Vec_WecAlloc( 100 );
Vec_Int_t * vUsed = Vec_IntStart( Vec_WecSize(vXors) );
Vec_Int_t * vFound = Vec_IntAlloc( 100 ); int Item, k, Obj;
while ( (Item = Gia_ManMulFindMaxSize(vXors, vUsed)) != -1 ) {
Vec_Int_t * vTemp = Vec_WecEntry(vXors, Item);
Vec_Int_t * vNew = Vec_WecPushLevel( vSets );
Vec_IntPush( vNew, Item );
Vec_IntWriteEntry( vUsed, Item, 1 );
Vec_IntClear( vFound );
Vec_IntAppend( vFound, vTemp );
while ( (Item = Gia_ManMulFindMaxOverlap(vXors, vUsed, vFound)) != -1 ) {
Vec_IntPush( vNew, Item );
Vec_IntWriteEntry( vUsed, Item, 1 );
vTemp = Vec_WecEntry(vXors, Item);
Vec_IntForEachEntry( vTemp, Obj, k )
Vec_IntPushUnique( vFound, Obj );
}
}
Vec_IntFree( vUsed );
Vec_IntFree( vFound );
return vSets;
}
int Gia_ManMulFindOne( Gia_Man_t * p, Vec_Wec_t * vXors, Vec_Int_t * vSet, Vec_Int_t * vMap, Vec_Int_t * vA, Vec_Int_t * vB, int fVerbose )
{
Vec_Int_t * vObjs = Vec_IntAlloc( 100 ); int i, j, Obj, Obj1, Obj2;
Vec_IntForEachEntry( vSet, Obj, i )
Vec_IntAppend( vObjs, Vec_WecEntry(vXors, Obj) );
Vec_IntForEachEntry( vObjs, Obj, i )
Vec_IntAddToEntry( vMap, Obj, 1 );
Vec_IntForEachEntry( vSet, Obj, i ) {
Vec_Int_t * vTemp = Vec_WecEntry(vXors, Obj); int k = 0;
Vec_IntForEachEntryDouble( vTemp, Obj1, Obj2, j )
if ( Vec_IntEntry(vMap, Obj1) > 1 || Vec_IntEntry(vMap, Obj2) > 1 )
Vec_IntWriteEntry(vTemp, k++, Obj1), Vec_IntWriteEntry(vTemp, k++, Obj2);
Vec_IntShrink( vTemp, k );
}
Vec_IntForEachEntry( vObjs, Obj, i )
Vec_IntWriteEntry( vMap, Obj, 0 );
Vec_IntClear( vObjs );
Vec_IntForEachEntry( vSet, Obj, i )
Vec_IntAppend( vObjs, Vec_WecEntry(vXors, Obj) );
if ( Vec_IntSize(vObjs) == 0 ) {
Vec_IntFree(vObjs);
return 0;
}
Vec_IntClear( vA );
Vec_IntClear( vB );
Vec_IntPush( vA, Vec_IntPop(vObjs) );
Vec_IntPush( vB, Vec_IntPop(vObjs) );
while ( Vec_IntSize(vObjs) > 0 ) {
int k = 0;
Vec_IntForEachEntryDouble( vObjs, Obj1, Obj2, j ) {
if ( Vec_IntFind(vA, Obj1) >= 0 )
Vec_IntPushUnique(vB, Obj2);
else if ( Vec_IntFind(vA, Obj2) >= 0 )
Vec_IntPushUnique(vB, Obj1);
else if ( Vec_IntFind(vB, Obj1) >= 0 )
Vec_IntPushUnique(vA, Obj2);
else if ( Vec_IntFind(vB, Obj2) >= 0 )
Vec_IntPushUnique(vA, Obj1);
else {
Vec_IntWriteEntry(vObjs, k++, Obj1);
Vec_IntWriteEntry(vObjs, k++, Obj2);
}
}
Vec_IntShrink( vObjs, k );
}
Vec_IntSort( vA, 0 );
Vec_IntSort( vB, 0 );
Vec_IntClear( vObjs );
Vec_IntForEachEntry( vSet, Obj, i )
Vec_IntAppend( vObjs, Vec_WecEntry(vXors, Obj) );
Vec_IntForEachEntryDouble( vObjs, Obj1, Obj2, j )
if ( !((Vec_IntFind(vA, Obj1) >= 0 && Vec_IntFind(vB, Obj2) >= 0) ||
(Vec_IntFind(vA, Obj2) >= 0 && Vec_IntFind(vB, Obj1) >= 0)) ) {
if ( fVerbose )
printf( "Internal verification failed.\n" );
Vec_IntFree( vObjs );
Vec_IntClear( vA );
Vec_IntClear( vB );
return 0;
}
if ( fVerbose )
printf( "Generated system with %d+%d+%d=%d variables and %d equations.\n",
Vec_IntSize(vA),Vec_IntSize(vB),Vec_IntSize(vSet),
Vec_IntSize(vA)+Vec_IntSize(vB)+Vec_IntSize(vSet), Vec_IntSize(vObjs)/2 );
Vec_IntFree( vObjs );
return 1;
}
Vec_Wec_t * Gia_ManMulFindAInputs2( Gia_Man_t * p, int fVerbose )
{
Vec_Wec_t * vMuls = Vec_WecAlloc( 10 );
Vec_Wec_t * vXors = Gia_ManMulFindXors2( p );
Vec_Wec_t * vSets = Gia_ManMulFindSets( p, vXors );
Vec_Int_t * vMap = Vec_IntStart( Gia_ManObjNum(p) );
Vec_Int_t * vA = Vec_IntAlloc( 100 );
Vec_Int_t * vB = Vec_IntAlloc( 100 );
Vec_Int_t * vSet; int i;
Vec_WecForEachLevel( vSets, vSet, i )
{
if ( !Gia_ManMulFindOne(p, vXors, vSet, vMap, vA, vB, fVerbose) )
continue;
Vec_IntAppend( Vec_WecPushLevel(vMuls), vA );
Vec_IntAppend( Vec_WecPushLevel(vMuls), vB );
Vec_WecPushLevel(vMuls);
}
Vec_WecFree( vXors );
Vec_WecFree( vSets );
Vec_IntFree( vMap );
Vec_IntFree( vA );
Vec_IntFree( vB );
return vMuls;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManMulFindAddEntry1( Vec_Int_t * vPairs, int Obj )
{
int Entry, Sum, k;
Vec_IntForEachEntryDouble( vPairs, Entry, Sum, k )
if ( Obj == Entry ) {
Vec_IntAddToEntry( vPairs, k+1, 1 );
break;
}
if ( k == Vec_IntSize(vPairs) )
Vec_IntPushTwo( vPairs, Obj, 1 );
}
Vec_Int_t * Gia_ManMulFindCounts( Vec_Wec_t * vCuts4, Vec_Int_t * vSet )
{
Vec_Int_t * vCounts = Vec_IntAlloc( 10 );
int i, k, Obj, Item;
Vec_IntForEachEntry( vSet, Item, i ) {
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
Vec_IntForEachEntryStart( vCut, Obj, k, 1 )
Gia_ManMulFindAddEntry1( vCounts, Obj );
}
return vCounts;
}
int Gia_ManMulFindNextEntry( Vec_Wec_t * vCuts4, Vec_Int_t * vSet, int Entry )
{
int i, Item;
Vec_IntForEachEntry( vSet, Item, i ) {
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
if ( Vec_IntSize(vCut) == 0 )
continue;
assert( Vec_IntSize(vCut) == 3 );
int RetValue = -1;
if ( Vec_IntEntry(vCut, 1) == Entry )
RetValue = Vec_IntEntry(vCut, 2);
if ( Vec_IntEntry(vCut, 2) == Entry )
RetValue = Vec_IntEntry(vCut, 1);
if ( RetValue == -1 )
continue;
Vec_IntClear( vCut );
return RetValue;
}
return -1;
}
void Gia_ManMulFindArg1( Vec_Wec_t * vCuts4, Vec_Int_t * vSet, Vec_Int_t * vArg1 )
{
Vec_Int_t * vCounts = Gia_ManMulFindCounts( vCuts4, vSet );
int Entry = -1, Sum, k;
Vec_IntClear( vArg1 );
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k )
if ( Sum == 1 ) {
Vec_IntPush( vArg1, Entry );
break;
}
assert( Entry != -1 );
while ( (Entry = Gia_ManMulFindNextEntry(vCuts4, vSet, Entry)) != -1 )
Vec_IntPush( vArg1, Entry );
Vec_IntFree( vCounts );
}
int Gia_ManMulFindNextEntryCount( Vec_Int_t * vCounts, int Entry0 )
{
int Entry, Sum, k;
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k )
if ( Entry == Entry0 )
return Sum;
return -1;
}
int Gia_ManMulFindNextEntry2( Vec_Wec_t * vCuts4, Vec_Int_t * vSet, int Entry, Vec_Int_t * vCounts, int * pEntry0, int * pEntry1 )
{
int i, Item;
Vec_IntForEachEntry( vSet, Item, i ) {
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
if ( Vec_IntSize(vCut) == 0 )
continue;
assert( Vec_IntSize(vCut) == 4 );
int Entry0, Entry1, iPlace = Vec_IntFind( vCut, Entry );
if ( iPlace == -1 )
continue;
if ( iPlace == 1 )
Entry0 = Vec_IntEntry(vCut, 2), Entry1 = Vec_IntEntry(vCut, 3);
else if ( iPlace == 2 )
Entry0 = Vec_IntEntry(vCut, 1), Entry1 = Vec_IntEntry(vCut, 3);
else if ( iPlace == 3 )
Entry0 = Vec_IntEntry(vCut, 1), Entry1 = Vec_IntEntry(vCut, 2);
else assert( 0 );
int Count0 = Gia_ManMulFindNextEntryCount(vCounts, Entry0);
int Count1 = Gia_ManMulFindNextEntryCount(vCounts, Entry1);
*pEntry0 = Count0 <= Count1 ? Entry0 : Entry1;
*pEntry1 = Count0 <= Count1 ? Entry1 : Entry0;
// remove entries
Vec_IntForEachEntry( vSet, Item, i ) {
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
if ( Vec_IntSize(vCut) == 0 )
continue;
if ( Vec_IntFind( vCut, Entry ) >= 0 )
Vec_IntClear( vCut );
}
return 1;
}
return 0;
}
void Gia_ManMulFindArg2( Vec_Wec_t * vCuts5, Vec_Int_t * vSet, Vec_Int_t * vArg2, int Entry0, int Entry1 )
{
Vec_Int_t * vCounts = Gia_ManMulFindCounts( vCuts5, vSet );
int Entry, Sum, k, SumMin = ABC_INFINITY, SumMax = 0;
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k ) {
SumMin = Abc_MinInt( SumMin, Sum );
SumMax = Abc_MaxInt( SumMax, Sum );
}
Vec_IntClear( vArg2 );
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k )
if ( Entry == Entry0 || Entry == Entry1 ) {
Vec_IntPush( vArg2, Entry == Entry0 ? Entry1 : Entry0 );
Vec_IntPush( vArg2, Entry );
break;
}
Entry = Vec_IntEntry(vArg2, 1);
while ( Gia_ManMulFindNextEntry2(vCuts5, vSet, Entry, vCounts, &Entry0, &Entry1) )
Vec_IntPushTwo( vArg2, Entry0, Entry1 ), Entry = Entry1;
Vec_IntFree( vCounts );
}
void Gia_ManMulFindAddEntry( Vec_Int_t * vPairs, int Obj0, int Obj1 )
{
int Entry0, Entry1, Sum, k;
Vec_IntForEachEntryTriple( vPairs, Entry0, Entry1, Sum, k )
if ( Obj0 == Entry0 && Obj1 == Entry1 ) {
Vec_IntAddToEntry( vPairs, k+2, 1 );
break;
}
if ( k == Vec_IntSize(vPairs) )
Vec_IntPushThree( vPairs, Obj0, Obj1, 1 );
}
Vec_Wec_t * Gia_ManMulFindBInputs2( Gia_Man_t * p, Vec_Wec_t * vCuts4, Vec_Wec_t * vCuts5, int fVerbose )
{
Vec_Wec_t * vRes = Vec_WecAlloc( 10 );
Vec_Int_t * vPairs = Vec_IntAlloc( 1000 );
Vec_Int_t * vSet = Vec_IntAlloc( 100 );
Vec_Int_t * vCut, * vArg1, * vArg2;
int i, j, k, n, Entry0, Entry1, Sum, Obj0, Obj1;
Vec_WecForEachLevel( vCuts4, vCut, i )
Vec_IntForEachEntryStart( vCut, Obj0, j, 1 )
Vec_IntForEachEntryStart( vCut, Obj1, k, j+1 )
Gia_ManMulFindAddEntry( vPairs, Obj0, Obj1 );
Vec_IntForEachEntryTriple( vPairs, Entry0, Entry1, Sum, n ) {
if ( Sum < 3 )
continue;
Vec_IntClear( vSet );
Vec_WecForEachLevel( vCuts4, vCut, i )
Vec_IntForEachEntryStart( vCut, Obj0, j, 1 )
Vec_IntForEachEntryStart( vCut, Obj1, k, j+1 )
if ( Obj0 == Entry0 && Obj1 == Entry1 ) {
Vec_IntPush( vSet, i );
Vec_IntDrop( vCut, k );
Vec_IntDrop( vCut, j );
j = k = Vec_IntSize(vCut);
}
vArg1 = Vec_WecPushLevel(vRes);
vArg2 = Vec_WecPushLevel(vRes);
Vec_WecPushLevel(vRes);
Gia_ManMulFindArg1( vCuts4, vSet, vArg1 );
// find overlapping with arg1 and remove nodes in arg1
Vec_IntClear( vSet );
Vec_WecForEachLevel( vCuts5, vCut, i )
if ( Gia_ManMulFindGetOverlap2(vCut, vArg1) ) {
k = 1;
Vec_IntForEachEntryStart( vCut, Obj0, j, 1 )
if ( Vec_IntFind(vArg1, Obj0) == -1 )
Vec_IntWriteEntry( vCut, k++, Obj0 );
Vec_IntShrink( vCut, k );
Vec_IntPush( vSet, i );
}
Gia_ManMulFindArg2( vCuts5, vSet, vArg2, Entry0, Entry1 );
}
Vec_IntFree( vSet );
Vec_IntFree( vPairs );
return vRes;
}
/**Function*************************************************************
Synopsis []
@ -331,6 +728,7 @@ Vec_Wrd_t * Gia_ManMulFindSim( Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, int fSigned
}
void Gia_ManMulFindOutputs( Gia_Man_t * p, Vec_Wec_t * vTerms, int fVerbose )
{
Abc_Random(1);
for ( int m = 0; m < Vec_WecSize(vTerms)/3; m++ ) {
Vec_Int_t * vIn0 = Vec_WecEntry(vTerms, 3*m+0);
Vec_Int_t * vIn1 = Vec_WecEntry(vTerms, 3*m+1);
@ -341,46 +739,47 @@ void Gia_ManMulFindOutputs( Gia_Man_t * p, Vec_Wec_t * vTerms, int fVerbose )
Vec_Wrd_t * vSimS = Gia_ManMulFindSim( vSim0, vSim1, 1 );
Vec_Int_t * vTfo = Gia_ManMulFindTfo( p, vIn0, vIn1 );
Vec_Wrd_t * vSims = Gia_ManMulFindSimCone( p, vIn0, vIn1, vSim0, vSim1, vTfo );
Vec_Int_t * vOutU = Vec_IntAlloc( 100 );
Vec_Int_t * vOutS = Vec_IntAlloc( 100 );
word Word; int w, iPlace;
assert( Vec_IntSize(vOut) == 0 );
Vec_WrdForEachEntry( vSimU, Word, w ) {
if ( (iPlace = Vec_WrdFind(vSims, Word)) >= 0 )
Vec_IntPush( vOut, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 0) );
Vec_IntPush( vOutU, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 0) );
else if ( (iPlace = Vec_WrdFind(vSims, ~Word)) >= 0 )
Vec_IntPush( vOut, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 1) );
Vec_IntPush( vOutU, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 1) );
else
break;
Vec_IntPush( vOutU, -1 );
}
if ( w == Vec_WrdSize(vSimU) )
Vec_IntPush(vOut, 0);
else
Vec_IntClear(vOut);
if ( Vec_IntSize(vOut) == 0 )
Vec_WrdForEachEntry( vSimS, Word, w ) {
if ( (iPlace = Vec_WrdFind(vSims, Word)) >= 0 )
Vec_IntPush( vOutS, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 0) );
else if ( (iPlace = Vec_WrdFind(vSims, ~Word)) >= 0 )
Vec_IntPush( vOutS, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 1) );
else
Vec_IntPush( vOutS, -1 );
}
assert( Vec_IntSize(vOut) == 0 );
if ( Vec_IntCountEntry(vOutU, -1) < Vec_IntSize(vOutU) ||
Vec_IntCountEntry(vOutS, -1) < Vec_IntSize(vOutS) )
{
Vec_IntClear(vOut);
Vec_WrdForEachEntry( vSimS, Word, w ) {
if ( (iPlace = Vec_WrdFind(vSims, Word)) >= 0 )
Vec_IntPush( vOut, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 0) );
else if ( (iPlace = Vec_WrdFind(vSims, ~Word)) >= 0 )
Vec_IntPush( vOut, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 1) );
else
break;
}
if ( w == Vec_WrdSize(vSimS) )
Vec_IntPush(vOut, 1);
if ( Vec_IntCountEntry(vOutU, -1) < Vec_IntCountEntry(vOutS, -1) )
Vec_IntAppend( vOut, vOutU ), Vec_IntPush(vOut, 0);
else
Vec_IntClear(vOut);
Vec_IntAppend( vOut, vOutS ), Vec_IntPush(vOut, 1);
}
else
{
Vec_IntClear(vIn0);
Vec_IntClear(vIn1);
}
Vec_WrdFree( vSim0 );
Vec_WrdFree( vSim1 );
Vec_WrdFree( vSimU );
Vec_WrdFree( vSimS );
Vec_WrdFree( vSims );
Vec_IntFree( vTfo );
if ( Vec_IntSize(vOut) )
continue;
Vec_IntClear(vIn0);
Vec_IntClear(vIn1);
Vec_IntFree( vOutU );
Vec_IntFree( vOutS );
}
Vec_WecRemoveEmpty( vTerms );
}
@ -413,7 +812,7 @@ Vec_Ptr_t * Gia_ManMulFindCuts( Gia_Man_t * p, int nCutNum, int fVerbose )
Vec_Wec_t * Gia_ManMulFindA( Gia_Man_t * p, Vec_Wec_t * vCuts3, int fVerbose )
{
Vec_Wec_t * vXors = Gia_ManMulFindXors( p, vCuts3, fVerbose );
Vec_Wec_t * vTerms = Gia_ManMulFindAInputs( p, vXors, fVerbose );
Vec_Wec_t * vTerms = Gia_ManMulFindAInputs2( p, fVerbose );
if ( Vec_WecSize(vTerms) )
Gia_ManMulFindOutputs( p, vTerms, fVerbose );
Vec_WecFree( vXors );
@ -423,7 +822,7 @@ Vec_Wec_t * Gia_ManMulFindB( Gia_Man_t * p, Vec_Wec_t * vCuts4, Vec_Wec_t * vCut
{
Vec_Wec_t * vTerms = Vec_WecAlloc( 12 );
if ( Vec_WecSize(vCuts4) && Vec_WecSize(vCuts5) )
vTerms = Gia_ManMulFindBInputs( p, vCuts4, vCuts5, fVerbose );
vTerms = Gia_ManMulFindBInputs2( p, vCuts4, vCuts5, fVerbose );
if ( Vec_WecSize(vTerms) )
Gia_ManMulFindOutputs( p, vTerms, fVerbose );
return vTerms;
@ -432,8 +831,12 @@ void Gia_ManMulFindPrintSet( Vec_Int_t * vSet, int fLit, int fSkipLast )
{
int i, Temp, Limit = Vec_IntSize(vSet) - fSkipLast;
printf( "{" );
Vec_IntForEachEntryStop( vSet, Temp, i, Limit )
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
Vec_IntForEachEntryStop( vSet, Temp, i, Limit ) {
if ( Temp == -1 )
printf( "n/a%s", i < Limit-1 ? " ":"" );
else
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
}
printf( "}" );
}
void Gia_ManMulFindPrintOne( Vec_Wec_t * vTerms, int m, int fBooth )
@ -441,7 +844,7 @@ void Gia_ManMulFindPrintOne( Vec_Wec_t * vTerms, int m, int fBooth )
Vec_Int_t * vIn0 = Vec_WecEntry(vTerms, 3*m+0);
Vec_Int_t * vIn1 = Vec_WecEntry(vTerms, 3*m+1);
Vec_Int_t * vOut = Vec_WecEntry(vTerms, 3*m+2);
printf( "%sooth %ssigned : ", fBooth ? "B" : "Non-b", Vec_IntEntryLast(vOut) ? "" : "un" );
printf( "%sooth %ssigned %d x %d: ", fBooth ? "B" : "Non-b", Vec_IntEntryLast(vOut) ? "" : "un", Vec_IntSize(vIn0), Vec_IntSize(vIn1) );
Gia_ManMulFindPrintSet( vIn0, 0, 0 );
printf( " * " );
Gia_ManMulFindPrintSet( vIn1, 0, 0 );