mirror of https://github.com/YosysHQ/abc.git
Experiments with detecting multipliers.
This commit is contained in:
parent
e824cca0ca
commit
807f6ddacf
|
|
@ -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 );
|
||||
|
|
|
|||
Loading…
Reference in New Issue