mirror of https://github.com/YosysHQ/abc.git
New multi-output PLA reader and preprocessor (read_plamo) (added dist-1 merge).
This commit is contained in:
parent
e06c04a3ef
commit
3c3a770a17
|
|
@ -1043,14 +1043,17 @@ usage:
|
|||
***********************************************************************/
|
||||
int IoCommandReadPlaMo( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern Abc_Ntk_t * Mop_ManTest( char * pFileName, int fVerbose );
|
||||
extern Abc_Ntk_t * Mop_ManTest( char * pFileName, int fMerge, int fVerbose );
|
||||
Abc_Ntk_t * pNtk;
|
||||
int c, fVerbose = 0;
|
||||
int c, fMerge = 0, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "mvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'm':
|
||||
fMerge ^= 1;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
|
|
@ -1063,7 +1066,7 @@ int IoCommandReadPlaMo( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
if ( argc != globalUtilOptind + 1 )
|
||||
goto usage;
|
||||
// get the input file name
|
||||
pNtk = Mop_ManTest( argv[globalUtilOptind], fVerbose );
|
||||
pNtk = Mop_ManTest( argv[globalUtilOptind], fMerge, fVerbose );
|
||||
if ( pNtk == NULL )
|
||||
return 1;
|
||||
// replace the current network
|
||||
|
|
@ -1072,8 +1075,9 @@ int IoCommandReadPlaMo( Abc_Frame_t * pAbc, int argc, char ** argv )
|
|||
return 0;
|
||||
|
||||
usage:
|
||||
fprintf( pAbc->Err, "usage: read_plamo [-vh] <file>\n" );
|
||||
fprintf( pAbc->Err, "usage: read_plamo [-mvh] <file>\n" );
|
||||
fprintf( pAbc->Err, "\t reads the network in multi-output PLA\n" );
|
||||
fprintf( pAbc->Err, "\t-m : toggle dist-1 merge for cubes with identical outputs [default = %s]\n", fMerge? "yes":"no" );
|
||||
fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes":"no" );
|
||||
fprintf( pAbc->Err, "\t-h : prints the command summary\n" );
|
||||
fprintf( pAbc->Err, "\tfile : the name of a file to read\n" );
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ struct Mop_Man_t_
|
|||
Vec_Wrd_t * vWordsIn;
|
||||
Vec_Wrd_t * vWordsOut;
|
||||
Vec_Int_t * vCubes;
|
||||
Vec_Int_t * vFree;
|
||||
};
|
||||
|
||||
static inline int Mop_ManIsSopSymb( char c ) { return c == '0' || c == '1' || c == '-'; }
|
||||
|
|
@ -65,11 +66,12 @@ Mop_Man_t * Mop_ManAlloc( int nIns, int nOuts, int nCubes )
|
|||
Mop_Man_t * p = ABC_CALLOC( Mop_Man_t, 1 );
|
||||
p->nIns = nIns;
|
||||
p->nOuts = nOuts;
|
||||
p->nWordsIn = Abc_Bit6WordNum( 2*nIns );
|
||||
p->nWordsIn = Abc_Bit6WordNum( 2 * nIns );
|
||||
p->nWordsOut = Abc_Bit6WordNum( nOuts );
|
||||
p->vWordsIn = Vec_WrdStart( p->nWordsIn * nCubes );
|
||||
p->vWordsOut = Vec_WrdStart( p->nWordsOut * nCubes );
|
||||
p->vCubes = Vec_IntAlloc( nCubes );
|
||||
p->vWordsIn = Vec_WrdStart( 2 * p->nWordsIn * nCubes );
|
||||
p->vWordsOut = Vec_WrdStart( 2 * p->nWordsOut * nCubes );
|
||||
p->vCubes = Vec_IntAlloc( 2 * nCubes );
|
||||
p->vFree = Vec_IntAlloc( 2 * nCubes );
|
||||
return p;
|
||||
}
|
||||
void Mop_ManStop( Mop_Man_t * p )
|
||||
|
|
@ -77,6 +79,7 @@ void Mop_ManStop( Mop_Man_t * p )
|
|||
Vec_WrdFree( p->vWordsIn );
|
||||
Vec_WrdFree( p->vWordsOut );
|
||||
Vec_IntFree( p->vCubes );
|
||||
Vec_IntFree( p->vFree );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
|
|
@ -196,26 +199,31 @@ Mop_Man_t * Mop_ManRead( char * pFileName )
|
|||
Vec_IntPush( p->vCubes, iCube );
|
||||
pToken = strtok( NULL, "\n" );
|
||||
}
|
||||
for ( ; iCube < 2 * nCubes; iCube++ )
|
||||
Vec_IntPush( p->vFree, iCube );
|
||||
ABC_FREE( pBuffer );
|
||||
return p;
|
||||
}
|
||||
void Mop_ManPrintOne( Mop_Man_t * p, int iCube )
|
||||
{
|
||||
int k;
|
||||
char Symb[4] = { '-', '0', '1', '?' };
|
||||
word * pCubeIn = Mop_ManCubeIn( p, iCube );
|
||||
word * pCubeOut = Mop_ManCubeOut( p, iCube );
|
||||
for ( k = 0; k < p->nIns; k++ )
|
||||
printf( "%c", Symb[Abc_TtGetQua(pCubeIn, k)] );
|
||||
printf( " " );
|
||||
for ( k = 0; k < p->nOuts; k++ )
|
||||
printf( "%d", Abc_TtGetBit(pCubeOut, k) );
|
||||
printf( "\n" );
|
||||
}
|
||||
void Mop_ManPrint( Mop_Man_t * p )
|
||||
{
|
||||
int i, k, iCube;
|
||||
int i, iCube;
|
||||
printf( ".%d\n", p->nIns );
|
||||
printf( ".%d\n", p->nOuts );
|
||||
Vec_IntForEachEntry( p->vCubes, iCube, i )
|
||||
{
|
||||
char Symb[4] = { '-', '0', '1', '?' };
|
||||
word * pCubeIn = Mop_ManCubeIn( p, iCube );
|
||||
word * pCubeOut = Mop_ManCubeOut( p, iCube );
|
||||
for ( k = 0; k < p->nIns; k++ )
|
||||
printf( "%c", Symb[Abc_TtGetQua(pCubeIn, k)] );
|
||||
printf( " " );
|
||||
for ( k = 0; k < p->nOuts; k++ )
|
||||
printf( "%d", Abc_TtGetBit(pCubeOut, k) );
|
||||
printf( "\n" );
|
||||
}
|
||||
Mop_ManPrintOne( p, iCube );
|
||||
printf( ".e\n" );
|
||||
}
|
||||
|
||||
|
|
@ -252,6 +260,18 @@ static inline Vec_Wec_t * Mop_ManCreateGroups( Mop_Man_t * p )
|
|||
Vec_WecPush( vGroups, Mop_ManCountOnes(Mop_ManCubeIn(p, iCube), p->nWordsIn), iCube );
|
||||
return vGroups;
|
||||
}
|
||||
static inline int Mop_ManUnCreateGroups( Mop_Man_t * p, Vec_Wec_t * vGroups )
|
||||
{
|
||||
int i, c1, iCube1;
|
||||
int nBefore = Vec_IntSize(p->vCubes);
|
||||
Vec_Int_t * vGroup;
|
||||
Vec_IntClear( p->vCubes );
|
||||
Vec_WecForEachLevel( vGroups, vGroup, i )
|
||||
Vec_IntForEachEntry( vGroup, iCube1, c1 )
|
||||
if ( iCube1 != -1 )
|
||||
Vec_IntPush( p->vCubes, iCube1 );
|
||||
return nBefore - Vec_IntSize(p->vCubes);
|
||||
}
|
||||
static inline int Mop_ManCheckContain( word * pBig, word * pSmall, int nWords )
|
||||
{
|
||||
int w;
|
||||
|
|
@ -260,79 +280,323 @@ static inline int Mop_ManCheckContain( word * pBig, word * pSmall, int nWords )
|
|||
return 0;
|
||||
return 1;
|
||||
}
|
||||
static inline void Mop_ManRemoveEmpty( Mop_Man_t * p )
|
||||
{
|
||||
int w, i, k = 0, iCube;
|
||||
Vec_IntForEachEntry( p->vCubes, iCube, i )
|
||||
{
|
||||
word * pCube = Mop_ManCubeOut( p, iCube );
|
||||
for ( w = 0; w < p->nWordsOut; w++ )
|
||||
if ( pCube[w] )
|
||||
break;
|
||||
if ( w < p->nWordsOut )
|
||||
Vec_IntWriteEntry( p->vCubes, k++, iCube );
|
||||
}
|
||||
Vec_IntShrink( p->vCubes, k );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
// check containment of input parts of two cubes
|
||||
static inline int Mop_ManCheckDist1( word * pCube1, word * pCube2, int nWords )
|
||||
{
|
||||
int w, fFound1 = 0;
|
||||
for ( w = 0; w < nWords; w++ )
|
||||
{
|
||||
word Xor = pCube1[w] ^ pCube2[w];
|
||||
if ( Xor == 0 ) // equal
|
||||
continue;
|
||||
if ( (Xor ^ (Xor >> 1)) & ABC_CONST(0x5555555555555555) ) // not pairs
|
||||
return 0;
|
||||
Xor &= (Xor >> 1) & ABC_CONST(0x5555555555555555);
|
||||
if ( Xor == 0 ) // not equal and not distance-1
|
||||
return 0;
|
||||
if ( fFound1 ) // distance-2 or more
|
||||
return 0;
|
||||
if ( (Xor & (Xor-1)) ) // distance-2 or more
|
||||
return 0;
|
||||
fFound1 = 1; // distance 1 so far
|
||||
}
|
||||
return fFound1;
|
||||
}
|
||||
// compresses cubes in the group
|
||||
static inline void Map_ManGroupCompact( Vec_Int_t * vGroup )
|
||||
{
|
||||
int i, Entry, k = 0;
|
||||
Vec_IntForEachEntry( vGroup, Entry, i )
|
||||
if ( Entry != -1 )
|
||||
Vec_IntWriteEntry( vGroup, k++, Entry );
|
||||
Vec_IntShrink( vGroup, k );
|
||||
}
|
||||
// takes cubes with identical literal count and removes duplicates
|
||||
int Mop_ManRemoveIdentical( Mop_Man_t * p, Vec_Int_t * vGroup )
|
||||
{
|
||||
int w, c1, c2, iCube1, iCube2, nEqual = 0;
|
||||
Vec_IntForEachEntry( vGroup, iCube1, c1 )
|
||||
if ( iCube1 != -1 )
|
||||
{
|
||||
word * pCube1Out, * pCube1 = Mop_ManCubeIn( p, iCube1 );
|
||||
Vec_IntForEachEntryStart( vGroup, iCube2, c2, c1+1 )
|
||||
if ( iCube2 != -1 )
|
||||
{
|
||||
word * pCube2Out, * pCube2 = Mop_ManCubeIn( p, iCube2 );
|
||||
if ( memcmp(pCube1, pCube2, sizeof(word)*p->nWordsIn) )
|
||||
continue;
|
||||
// merge cubes
|
||||
pCube1Out = Mop_ManCubeOut( p, iCube1 );
|
||||
pCube2Out = Mop_ManCubeOut( p, iCube2 );
|
||||
for ( w = 0; w < p->nWordsOut; w++ )
|
||||
pCube1Out[w] |= pCube2Out[w];
|
||||
Vec_IntWriteEntry( vGroup, c2, -1 );
|
||||
Vec_IntPush( p->vFree, iCube2 );
|
||||
nEqual++;
|
||||
}
|
||||
}
|
||||
if ( nEqual )
|
||||
Map_ManGroupCompact( vGroup );
|
||||
return nEqual;
|
||||
}
|
||||
// reduces the set of pairs
|
||||
Vec_Int_t * Mop_ManCompatiblePairs( Vec_Int_t * vPairs, int nObjs )
|
||||
{
|
||||
int i, Entry, Entry2;
|
||||
Vec_Int_t * vCounts = Vec_IntStart( nObjs );
|
||||
Vec_Int_t * vPairsNew = Vec_IntAlloc( Vec_IntSize(vPairs) );
|
||||
Vec_IntForEachEntry( vPairs, Entry, i )
|
||||
Vec_IntAddToEntry( vCounts, Entry, 1 );
|
||||
// include pairs which have those that appear only once
|
||||
Vec_IntForEachEntryDouble( vPairs, Entry, Entry2, i )
|
||||
if ( Vec_IntEntry(vCounts, Entry) == 1 || Vec_IntEntry(vCounts, Entry2) == 1 )
|
||||
{
|
||||
if ( Vec_IntEntry(vCounts, Entry) == 1 )
|
||||
Vec_IntPushTwo( vPairsNew, Entry, Entry2 );
|
||||
else
|
||||
Vec_IntPushTwo( vPairsNew, Entry2, Entry );
|
||||
Vec_IntWriteEntry( vCounts, Entry, -1 );
|
||||
Vec_IntWriteEntry( vCounts, Entry2, -1 );
|
||||
}
|
||||
// add those remaining pairs that are both present
|
||||
Vec_IntForEachEntryDouble( vPairs, Entry, Entry2, i )
|
||||
if ( Vec_IntEntry(vCounts, Entry) > 0 && Vec_IntEntry(vCounts, Entry2) > 0 )
|
||||
{
|
||||
Vec_IntPushTwo( vPairsNew, Entry, Entry2 );
|
||||
Vec_IntWriteEntry( vCounts, Entry, -1 );
|
||||
Vec_IntWriteEntry( vCounts, Entry2, -1 );
|
||||
}
|
||||
// add remaining pairs
|
||||
Vec_IntForEachEntryDouble( vPairs, Entry, Entry2, i )
|
||||
if ( Vec_IntEntry(vCounts, Entry) > 0 || Vec_IntEntry(vCounts, Entry2) > 0 )
|
||||
{
|
||||
if ( Vec_IntEntry(vCounts, Entry) > 0 )
|
||||
Vec_IntPushTwo( vPairsNew, Entry, Entry2 );
|
||||
else
|
||||
Vec_IntPushTwo( vPairsNew, Entry2, Entry );
|
||||
Vec_IntWriteEntry( vCounts, Entry, -1 );
|
||||
Vec_IntWriteEntry( vCounts, Entry2, -1 );
|
||||
}
|
||||
Vec_IntFree( vCounts );
|
||||
// verify the result
|
||||
if ( 0 )
|
||||
{
|
||||
Vec_Int_t * vTemp1 = Vec_IntDup( vPairs );
|
||||
Vec_Int_t * vTemp2 = Vec_IntDup( vPairsNew );
|
||||
Vec_IntUniqify( vTemp1 );
|
||||
Vec_IntUniqify( vTemp2 );
|
||||
assert( Vec_IntEqual( vTemp1, vTemp2 ) );
|
||||
Vec_IntFree( vTemp1 );
|
||||
Vec_IntFree( vTemp2 );
|
||||
}
|
||||
return vPairsNew;
|
||||
}
|
||||
// detects pairs of distance-1 cubes with identical outputs
|
||||
Vec_Int_t * Mop_ManFindDist1Pairs( Mop_Man_t * p, Vec_Int_t * vGroup )
|
||||
{
|
||||
int c1, c2, iCube1, iCube2;
|
||||
Vec_Int_t * vPairs = Vec_IntAlloc( 100 );
|
||||
Vec_IntForEachEntry( vGroup, iCube1, c1 )
|
||||
{
|
||||
word * pCube1Out, * pCube1 = Mop_ManCubeIn( p, iCube1 );
|
||||
Vec_IntForEachEntryStart( vGroup, iCube2, c2, c1+1 )
|
||||
{
|
||||
word * pCube2Out, * pCube2 = Mop_ManCubeIn( p, iCube2 );
|
||||
if ( !Mop_ManCheckDist1(pCube1, pCube2, p->nWordsIn) )
|
||||
continue;
|
||||
pCube1Out = Mop_ManCubeOut( p, iCube1 );
|
||||
pCube2Out = Mop_ManCubeOut( p, iCube2 );
|
||||
if ( !memcmp(pCube1Out, pCube2Out, sizeof(word)*p->nWordsOut) )
|
||||
Vec_IntPushTwo( vPairs, c1, c2 );
|
||||
}
|
||||
}
|
||||
return vPairs;
|
||||
}
|
||||
// merge distance-1 with identical output part
|
||||
int Mop_ManMergeDist1Pairs( Mop_Man_t * p, Vec_Int_t * vGroup, Vec_Int_t * vGroupPrev )
|
||||
{
|
||||
Vec_Int_t * vPairs = Mop_ManFindDist1Pairs( p, vGroup );
|
||||
Vec_Int_t * vPairsNew = Mop_ManCompatiblePairs( vPairs, Vec_IntSize(vGroup) );
|
||||
int w, i, c1, c2, nCubes = Vec_IntSize(vGroup) + Vec_IntSize(vGroupPrev);
|
||||
// move cubes to the previous group
|
||||
Vec_IntForEachEntryDouble( vPairsNew, c1, c2, i )
|
||||
{
|
||||
int iCubeNew = Vec_IntPop( p->vFree );
|
||||
|
||||
word * pCube = Mop_ManCubeIn( p, iCubeNew );
|
||||
word * pCube1 = Mop_ManCubeIn( p, Vec_IntEntry(vGroup, c1) );
|
||||
word * pCube2 = Mop_ManCubeIn( p, Vec_IntEntry(vGroup, c2) );
|
||||
|
||||
assert( Mop_ManCheckDist1(pCube1, pCube2, p->nWordsIn) );
|
||||
for ( w = 0; w < p->nWordsIn; w++ )
|
||||
pCube[w] = pCube1[w] & pCube2[w];
|
||||
|
||||
pCube = Mop_ManCubeOut( p, iCubeNew );
|
||||
pCube1 = Mop_ManCubeOut( p, Vec_IntEntry(vGroup, c1) );
|
||||
pCube2 = Mop_ManCubeOut( p, Vec_IntEntry(vGroup, c2) );
|
||||
|
||||
assert( !memcmp(pCube1, pCube2, sizeof(word)*p->nWordsOut) );
|
||||
for ( w = 0; w < p->nWordsOut; w++ )
|
||||
pCube[w] = pCube1[w];
|
||||
|
||||
Vec_IntPush( vGroupPrev, iCubeNew );
|
||||
}
|
||||
Vec_IntForEachEntry( vPairsNew, c1, i )
|
||||
{
|
||||
if ( Vec_IntEntry(vGroup, c1) == -1 )
|
||||
continue;
|
||||
Vec_IntPush( p->vFree, Vec_IntEntry(vGroup, c1) );
|
||||
Vec_IntWriteEntry( vGroup, c1, -1 );
|
||||
}
|
||||
if ( Vec_IntSize(vPairsNew) > 0 )
|
||||
Map_ManGroupCompact( vGroup );
|
||||
Vec_IntFree( vPairs );
|
||||
Vec_IntFree( vPairsNew );
|
||||
return nCubes - Vec_IntSize(vGroup) - Vec_IntSize(vGroupPrev);
|
||||
}
|
||||
int Mop_ManMergeDist1All( Mop_Man_t * p, Vec_Wec_t * vGroups )
|
||||
{
|
||||
Vec_Int_t * vGroup;
|
||||
int i, nEqual, nReduce, Count = 0;
|
||||
Vec_WecForEachLevelReverse( vGroups, vGroup, i )
|
||||
{
|
||||
if ( Vec_IntSize(vGroup) == 0 )
|
||||
continue;
|
||||
if ( i == 0 )
|
||||
{
|
||||
printf( "Detected constant-1 cover.\n" );
|
||||
fflush( stdout );
|
||||
return -1;
|
||||
}
|
||||
nEqual = Mop_ManRemoveIdentical( p, vGroup );
|
||||
nReduce = Mop_ManMergeDist1Pairs( p, vGroup, Vec_WecEntry(vGroups, i-1) );
|
||||
Count += nEqual + nReduce;
|
||||
//printf( "Group %3d : Equal =%5d. Reduce =%5d.\n", i, nEqual, nReduce );
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
// reduce contained cubes
|
||||
int Mop_ManMergeContainTwo( Mop_Man_t * p, Vec_Int_t * vGroup, Vec_Int_t * vGroup2 )
|
||||
{
|
||||
int w, c1, c2, iCube1, iCube2, Count = 0;
|
||||
Vec_IntForEachEntry( vGroup, iCube1, c1 )
|
||||
{
|
||||
word * pCube1Out, * pCube1 = Mop_ManCubeIn( p, iCube1 );
|
||||
Vec_IntForEachEntry( vGroup2, iCube2, c2 )
|
||||
if ( iCube2 != -1 )
|
||||
{
|
||||
word * pCube2Out, * pCube2 = Mop_ManCubeIn( p, iCube2 );
|
||||
if ( !Mop_ManCheckContain(pCube2, pCube1, p->nWordsIn) )
|
||||
continue;
|
||||
pCube1Out = Mop_ManCubeOut( p, iCube1 );
|
||||
pCube2Out = Mop_ManCubeOut( p, iCube2 );
|
||||
for ( w = 0; w < p->nWordsOut; w++ )
|
||||
pCube2Out[w] &= ~pCube1Out[w];
|
||||
for ( w = 0; w < p->nWordsOut; w++ )
|
||||
if ( pCube2Out[w] )
|
||||
break;
|
||||
if ( w < p->nWordsOut ) // has output literals
|
||||
continue;
|
||||
// remove larger cube
|
||||
Vec_IntWriteEntry( vGroup2, c2, -1 );
|
||||
Vec_IntPush( p->vFree, iCube2 );
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
if ( Count )
|
||||
Map_ManGroupCompact( vGroup2 );
|
||||
return Count;
|
||||
}
|
||||
int Mop_ManMergeContainAll( Mop_Man_t * p, Vec_Wec_t * vGroups )
|
||||
{
|
||||
Vec_Int_t * vGroup, * vGroup2;
|
||||
int i, k, Count = 0;
|
||||
Vec_WecForEachLevel( vGroups, vGroup, i )
|
||||
{
|
||||
Count += Mop_ManRemoveIdentical( p, vGroup );
|
||||
Vec_WecForEachLevelStart( vGroups, vGroup2, k, i+1 )
|
||||
Count += Mop_ManMergeContainTwo( p, vGroup, vGroup2 );
|
||||
}
|
||||
return Count;
|
||||
}
|
||||
void Mop_ManReduce2( Mop_Man_t * p )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
int nCubes = Vec_IntSize(p->vCubes);
|
||||
Vec_Wec_t * vGroups = Mop_ManCreateGroups( p );
|
||||
int nOutLits = Mop_ManCountOutputLits( p );
|
||||
int Count1 = Mop_ManMergeContainAll( p, vGroups );
|
||||
int Count2 = Mop_ManMergeDist1All( p, vGroups );
|
||||
int Count3 = Mop_ManMergeContainAll( p, vGroups );
|
||||
int Removed = Mop_ManUnCreateGroups( p, vGroups );
|
||||
int nOutLits2 = Mop_ManCountOutputLits( p );
|
||||
Vec_WecFree( vGroups );
|
||||
assert( Removed == Count1 + Count2 + Count3 );
|
||||
// report
|
||||
printf( "Cubes: %d -> %d. Contain = %d. Merge = %d. Contain = %d. Output lits: %d -> %d. ",
|
||||
nCubes, Vec_IntSize(p->vCubes), Count1, Count2, Count3, nOutLits, nOutLits2 );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Mop_ManReduce( Mop_Man_t * p )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
Vec_Int_t * vGroup, * vGroup2;
|
||||
int w, i, k, c1, c2, iCube1, iCube2;
|
||||
int nOutLits, nOutLits2, nEqual = 0, nContain = 0;
|
||||
int i, k, nOutLits, nOutLits2, nEqual = 0, nContain = 0;
|
||||
Vec_Wec_t * vGroups = Mop_ManCreateGroups( p );
|
||||
// initial stats
|
||||
nOutLits = Mop_ManCountOutputLits( p );
|
||||
// check identical cubes within each group
|
||||
Vec_WecForEachLevel( vGroups, vGroup, i )
|
||||
{
|
||||
Vec_IntForEachEntry( vGroup, iCube1, c1 )
|
||||
if ( iCube1 != -1 )
|
||||
{
|
||||
word * pCube1Out, * pCube1 = Mop_ManCubeIn( p, iCube1 );
|
||||
Vec_IntForEachEntryStart( vGroup, iCube2, c2, c1+1 )
|
||||
if ( iCube2 != -1 )
|
||||
{
|
||||
word * pCube2Out, * pCube2 = Mop_ManCubeIn( p, iCube2 );
|
||||
if ( memcmp(pCube1, pCube2, sizeof(word)*p->nWordsIn) )
|
||||
continue;
|
||||
// merge cubes
|
||||
pCube1Out = Mop_ManCubeOut( p, iCube1 );
|
||||
pCube2Out = Mop_ManCubeOut( p, iCube2 );
|
||||
for ( w = 0; w < p->nWordsOut; w++ )
|
||||
pCube1Out[w] |= pCube2Out[w];
|
||||
Vec_IntWriteEntry( vGroup, c2, -1 );
|
||||
nEqual++;
|
||||
}
|
||||
}
|
||||
}
|
||||
nEqual += Mop_ManRemoveIdentical( p, vGroup );
|
||||
// check contained cubes
|
||||
Vec_WecForEachLevel( vGroups, vGroup, i )
|
||||
{
|
||||
// compare cubes in vGroup with cubes containing more literals
|
||||
Vec_WecForEachLevelStart( vGroups, vGroup2, k, i+1 )
|
||||
{
|
||||
Vec_IntForEachEntry( vGroup, iCube1, c1 )
|
||||
if ( iCube1 != -1 )
|
||||
{
|
||||
word * pCube1Out, * pCube1 = Mop_ManCubeIn( p, iCube1 );
|
||||
Vec_IntForEachEntry( vGroup2, iCube2, c2 )
|
||||
if ( iCube2 != -1 )
|
||||
{
|
||||
word * pCube2Out, * pCube2 = Mop_ManCubeIn( p, iCube2 );
|
||||
if ( !Mop_ManCheckContain(pCube2, pCube1, p->nWordsIn) )
|
||||
continue;
|
||||
pCube1Out = Mop_ManCubeOut( p, iCube1 );
|
||||
pCube2Out = Mop_ManCubeOut( p, iCube2 );
|
||||
for ( w = 0; w < p->nWordsOut; w++ )
|
||||
pCube2Out[w] &= ~pCube1Out[w];
|
||||
for ( w = 0; w < p->nWordsOut; w++ )
|
||||
if ( pCube2Out[w] )
|
||||
break;
|
||||
if ( w < p->nWordsOut ) // has output literals
|
||||
continue;
|
||||
// remove larger cube
|
||||
Vec_IntWriteEntry( vGroup2, c2, -1 );
|
||||
nContain++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nContain += Mop_ManMergeContainTwo( p, vGroup, vGroup2 );
|
||||
// final stats
|
||||
nOutLits2 = Mop_ManCountOutputLits( p );
|
||||
// reload cubes
|
||||
Vec_IntClear( p->vCubes );
|
||||
Vec_WecForEachLevel( vGroups, vGroup, i )
|
||||
Vec_IntForEachEntry( vGroup, iCube1, c1 )
|
||||
if ( iCube1 != -1 )
|
||||
Vec_IntPush( p->vCubes, iCube1 );
|
||||
Mop_ManUnCreateGroups( p, vGroups );
|
||||
Vec_WecFree( vGroups );
|
||||
|
||||
printf( "Reduced %d equal and %d contained cubes. Output lits: %d -> %d. ", nEqual, nContain, nOutLits, nOutLits2 );
|
||||
// report
|
||||
printf( "Total = %d. Reduced %d equal and %d contained cubes. Output lits: %d -> %d. ", Vec_IntSize(p->vCubes), nEqual, nContain, nOutLits, nOutLits2 );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
}
|
||||
|
||||
|
|
@ -414,14 +678,18 @@ Abc_Ntk_t * Mop_ManDerive( Mop_Man_t * p, char * pFileName )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Abc_Ntk_t * Mop_ManTest( char * pFileName, int fVerbose )
|
||||
Abc_Ntk_t * Mop_ManTest( char * pFileName, int fMerge, int fVerbose )
|
||||
{
|
||||
Abc_Ntk_t * pNtk = NULL;
|
||||
Mop_Man_t * p = Mop_ManRead( pFileName );
|
||||
if ( p == NULL )
|
||||
return NULL;
|
||||
Mop_ManRemoveEmpty( p );
|
||||
//Mop_ManPrint( p );
|
||||
Mop_ManReduce( p );
|
||||
if ( fMerge )
|
||||
Mop_ManReduce2( p );
|
||||
else
|
||||
Mop_ManReduce( p );
|
||||
//Mop_ManPrint( p );
|
||||
pNtk = Mop_ManDerive( p, pFileName );
|
||||
Mop_ManStop( p );
|
||||
|
|
|
|||
Loading…
Reference in New Issue