blob: 2310de5fd3824e157465ba98ebbda8c0cea4bd44 [file] [log] [blame]
/**CFile****************************************************************
FileName [exor.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Exclusive sum-of-product minimization.]
Synopsis [Main procedure.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: exor.c,v 1.0 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
////////////////////////////////////////////////////////////////////////
/// ///
/// Implementation of EXORCISM - 4 ///
/// An Exclusive Sum-of-Product Minimizer ///
/// Alan Mishchenko <alanmi@ee.pdx.edu> ///
/// ///
////////////////////////////////////////////////////////////////////////
/// ///
/// Main Module ///
/// ESOP Minimization Task Coordinator ///
/// ///
/// 1) interprets command line ///
/// 2) calls the approapriate reading procedure ///
/// 3) calls the minimization module ///
/// ///
/// Ver. 1.0. Started - July 18, 2000. Last update - July 20, 2000 ///
/// Ver. 1.1. Started - July 24, 2000. Last update - July 29, 2000 ///
/// Ver. 1.4. Started - Aug 10, 2000. Last update - Aug 26, 2000 ///
/// Ver. 1.6. Started - Sep 11, 2000. Last update - Sep 15, 2000 ///
/// Ver. 1.7. Started - Sep 20, 2000. Last update - Sep 23, 2000 ///
/// ///
////////////////////////////////////////////////////////////////////////
/// This software was tested with the BDD package "CUDD", v.2.3.0 ///
/// by Fabio Somenzi ///
/// http://vlsi.colorado.edu/~fabio/ ///
////////////////////////////////////////////////////////////////////////
#include "exor.h"
ABC_NAMESPACE_IMPL_START
///////////////////////////////////////////////////////////////////////
/// GLOBAL VARIABLES ///
////////////////////////////////////////////////////////////////////////
// information about the cube cover
cinfo g_CoverInfo;
extern int s_fDecreaseLiterals;
////////////////////////////////////////////////////////////////////////
/// EXTERNAL FUNCTIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION main() ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Number of negative literals.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
/*
static int QCost[16][16] =
{
{ 1}, // 0
{ 1, 2}, // 1
{ 5, 5, 6}, // 2
{ 14, 14, 16, 18}, // 3
{ 20, 20, 20, 22, 24}, // 4
{ 32, 32, 32, 34, 36, 38}, // 5
{ 44, 44, 44, 44, 46, 48, 50}, // 6
{ 56, 56, 56, 56, 58, 60, 62, 64}, // 7
{ 0 }
};
*/
int GetQCost( int nVars, int nNegs )
{
int Extra;
assert( nVars >= nNegs );
if ( nVars == 0 )
return 1;
if ( nVars == 1 )
{
if ( nNegs == 0 ) return 1;
if ( nNegs == 1 ) return 2;
}
if ( nVars == 2 )
{
if ( nNegs <= 1 ) return 5;
if ( nNegs == 2 ) return 6;
}
if ( nVars == 3 )
{
if ( nNegs <= 1 ) return 14;
if ( nNegs == 2 ) return 16;
if ( nNegs == 3 ) return 18;
}
Extra = nNegs - nVars/2;
return 20 + 12 * (nVars - 4) + (Extra > 0 ? 2 * Extra : 0);
}
void GetQCostTest()
{
int i, k, Limit = 10;
for ( i = 0; i < Limit; i++ )
{
for ( k = 0; k <= i; k++ )
printf( "%4d ", GetQCost(i, k) );
printf( "\n" );
}
}
int ComputeQCost( Vec_Int_t * vCube )
{
int i, Entry, nLitsN = 0;
Vec_IntForEachEntry( vCube, Entry, i )
nLitsN += Abc_LitIsCompl(Entry);
return GetQCost( Vec_IntSize(vCube), nLitsN );
}
int ComputeQCostBits( Cube * p )
{
extern varvalue GetVar( Cube* pC, int Var );
int v, nLits = 0, nLitsN = 0;
for ( v = 0; v < g_CoverInfo.nVarsIn; v++ )
{
int Value = GetVar( p, v );
if ( Value == VAR_NEG )
nLitsN++;
else if ( Value == VAR_POS )
nLits++;
}
nLits += nLitsN;
return GetQCost( nLits, nLitsN );
}
int ToffoliGateCount( int controls, int lines )
{
switch ( controls )
{
case 0u:
case 1u:
return 0;
break;
case 2u:
return 1;
break;
case 3u:
return 4;
break;
case 4u:
return ( ( ( lines + 1 ) / 2 ) >= controls ) ? 8 : 10;
break;
default:
return ( ( ( lines + 1 ) / 2 ) >= controls ) ? 4 * ( controls - 2 ) : 8 * ( controls - 3 );
}
}
int ComputeQCostTcount( Vec_Int_t * vCube )
{
return 7 * ToffoliGateCount( Vec_IntSize( vCube ), g_CoverInfo.nVarsIn + 1 );
}
int ComputeQCostTcountBits( Cube * p )
{
extern varvalue GetVar( Cube* pC, int Var );
int v, nLits = 0;
for ( v = 0; v < g_CoverInfo.nVarsIn; v++ )
if ( GetVar( p, v ) != VAR_ABS )
nLits++;
return 7 * ToffoliGateCount( nLits, g_CoverInfo.nVarsIn + 1 );
/* maybe just: 7 * ToffoliGateCount( p->a, g_CoverInfo.nVarsIn + 1 ); */
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int ReduceEsopCover()
{
///////////////////////////////////////////////////////////////
// SIMPLIFICATION
////////////////////////////////////////////////////////////////////
int nIterWithoutImprovement = 0;
int nIterCount = 0;
int GainTotal;
int z;
do
{
//START:
if ( g_CoverInfo.Verbosity == 2 )
printf( "\nITERATION #%d\n\n", ++nIterCount );
else if ( g_CoverInfo.Verbosity == 1 )
printf( "." );
GainTotal = 0;
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
if ( nIterWithoutImprovement > (int)(g_CoverInfo.Quality>0) )
{
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|0 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
// if ( g_CoverInfo.Quality >= 2 && nIterWithoutImprovement == 2 )
// s_fDecreaseLiterals = 1;
}
while ( nIterWithoutImprovement < 1 + g_CoverInfo.Quality );
// improve the literal count
s_fDecreaseLiterals = 1;
for ( z = 0; z < 1; z++ )
{
if ( g_CoverInfo.Verbosity == 2 )
printf( "\nITERATION #%d\n\n", ++nIterCount );
else if ( g_CoverInfo.Verbosity == 1 )
printf( "." );
GainTotal = 0;
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
// if ( GainTotal )
// {
// nIterWithoutImprovement = 0;
// goto START;
// }
}
/* ////////////////////////////////////////////////////////////////////
// Print statistics
printf( "\nShallow simplification time is ";
cout << (float)(clk2 - clk1)/(float)(CLOCKS_PER_SEC) << " sec\n" );
printf( "Deep simplification time is ";
cout << (float)(Abc_Clock() - clk2)/(float)(CLOCKS_PER_SEC) << " sec\n" );
printf( "Cover after iterative simplification = " << s_nCubesInUse << endl;
printf( "Reduced by initial cube writing = " << g_CoverInfo.nCubesBefore-nCubesAfterWriting << endl;
printf( "Reduced by shallow simplification = " << nCubesAfterWriting-nCubesAfterShallow << endl;
printf( "Reduced by deep simplification = " << nCubesAfterWriting-s_nCubesInUse << endl;
// printf( "\nThe total number of cubes created = " << g_CoverInfo.cIDs << endl;
// printf( "Total number of places in a queque = " << s_nPosAlloc << endl;
// printf( "Minimum free places in queque-2 = " << s_nPosMax[0] << endl;
// printf( "Minimum free places in queque-3 = " << s_nPosMax[1] << endl;
// printf( "Minimum free places in queque-4 = " << s_nPosMax[2] << endl;
*/ ////////////////////////////////////////////////////////////////////
// write the number of cubes into cover information
assert ( g_CoverInfo.nCubesInUse + g_CoverInfo.nCubesFree == g_CoverInfo.nCubesAlloc );
// printf( "\nThe output cover is\n" );
// PrintCoverDebug( cout );
return 0;
}
//////////////////////////////////////////////////////////////////
// quite a good script
//////////////////////////////////////////////////////////////////
/*
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
do
{
PrintQuequeStats();
GainTotal = 0;
GainTotal += IterativelyApplyExorLink( DIST2, 0|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 0|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
if ( nIterWithoutImprovement > 2 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
}
if ( nIterWithoutImprovement > 6 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 12 );
nCubesAfterShallow = s_nCubesInUse;
*/
/*
// alu4 - 439
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
do
{
PrintQuequeStats();
GainTotal = 0;
GainTotal += IterativelyApplyExorLink( DIST2, 1|0|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
if ( nIterWithoutImprovement > 2 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
}
if ( nIterWithoutImprovement > 6 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 0|0|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 12 );
*/
/*
// alu4 - 412 cubes, 700 sec
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
int nIterCount = 0;
do
{
printf( "\nITERATION #" << ++nIterCount << endl << endl;
GainTotal = 0;
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
if ( nIterWithoutImprovement > 3 )
{
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
}
if ( nIterWithoutImprovement > 7 )
{
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 12 );
*/
/*
// pretty good script
// alu4 = 424 in 250 sec
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
int nIterCount = 0;
do
{
printf( "\nITERATION #" << ++nIterCount << " |";
for ( int k = 0; k < nIterWithoutImprovement; k++ )
printf( "*";
for ( ; k < 11; k++ )
printf( "_";
printf( "|" << endl << endl;
GainTotal = 0;
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
if ( nIterWithoutImprovement > 2 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
}
if ( nIterWithoutImprovement > 4 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 7 );
*/
/*
alu4 = 435 70 secs
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
int nIterCount = 0;
do
{
printf( "\nITERATION #" << ++nIterCount << endl << endl;
GainTotal = 0;
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 4 );
*/
/*
// the best previous
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
int nIterCount = 0;
int GainTotal;
do
{
if ( g_CoverInfo.Verbosity == 2 )
printf( "\nITERATION #" << ++nIterCount << endl << endl;
else if ( g_CoverInfo.Verbosity == 1 )
cout << '.';
GainTotal = 0;
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
if ( nIterWithoutImprovement > 1 )
{
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|0 );
GainTotal += IterativelyApplyExorLink( DIST3, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST2, 1|2|4 );
GainTotal += IterativelyApplyExorLink( DIST4, 1|2|0 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
// while ( nIterWithoutImprovement < 20 );
// while ( nIterWithoutImprovement < 7 );
while ( nIterWithoutImprovement < 1 + g_CoverInfo.Quality );
*/
/*
// the last tried
long clk1 = Abc_Clock();
int nIterWithoutImprovement = 0;
int nIterCount = 0;
int GainTotal;
do
{
if ( g_CoverInfo.Verbosity == 2 )
printf( "\nITERATION #" << ++nIterCount << endl << endl;
else if ( g_CoverInfo.Verbosity == 1 )
cout << '.';
GainTotal = 0;
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
if ( nIterWithoutImprovement > (int)(g_CoverInfo.Quality>0) )
{
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|0 );
GainTotal += IterativelyApplyExorLink2( 1|2|0 );
GainTotal += IterativelyApplyExorLink3( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|4 );
GainTotal += IterativelyApplyExorLink2( 1|2|4 );
GainTotal += IterativelyApplyExorLink4( 1|2|0 );
}
if ( GainTotal )
nIterWithoutImprovement = 0;
else
nIterWithoutImprovement++;
}
while ( nIterWithoutImprovement < 1 + g_CoverInfo.Quality );
*/
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void AddCubesToStartingCover( Vec_Wec_t * vEsop )
{
Vec_Int_t * vCube;
Cube * pNew;
int * s_Level2Var;
int * s_LevelValues;
int c, i, k, Lit, Out;
s_Level2Var = ABC_ALLOC( int, g_CoverInfo.nVarsIn );
s_LevelValues = ABC_ALLOC( int, g_CoverInfo.nVarsIn );
for ( i = 0; i < g_CoverInfo.nVarsIn; i++ )
s_Level2Var[i] = i;
g_CoverInfo.nLiteralsBefore = 0;
g_CoverInfo.QCostBefore = 0;
Vec_WecForEachLevel( vEsop, vCube, c )
{
// get the output of this cube
Out = -Vec_IntPop(vCube) - 1;
// fill in the cube with blanks
for ( i = 0; i < g_CoverInfo.nVarsIn; i++ )
s_LevelValues[i] = VAR_ABS;
Vec_IntForEachEntry( vCube, Lit, k )
{
if ( Abc_LitIsCompl(Lit) )
s_LevelValues[Abc_Lit2Var(Lit)] = VAR_NEG;
else
s_LevelValues[Abc_Lit2Var(Lit)] = VAR_POS;
}
// get the new cube
pNew = GetFreeCube();
// consider the need to clear the cube
if ( pNew->pCubeDataIn[0] ) // this is a recycled cube
{
for ( i = 0; i < g_CoverInfo.nWordsIn; i++ )
pNew->pCubeDataIn[i] = 0;
for ( i = 0; i < g_CoverInfo.nWordsOut; i++ )
pNew->pCubeDataOut[i] = 0;
}
InsertVarsWithoutClearing( pNew, s_Level2Var, g_CoverInfo.nVarsIn, s_LevelValues, Out );
// set literal counts
pNew->a = Vec_IntSize(vCube);
pNew->z = 1;
pNew->q = ComputeQCost(vCube);
// set the ID
pNew->ID = g_CoverInfo.cIDs++;
// skip through zero-ID
if ( g_CoverInfo.cIDs == 256 )
g_CoverInfo.cIDs = 1;
// add this cube to storage
CheckForCloseCubes( pNew, 1 );
g_CoverInfo.nLiteralsBefore += Vec_IntSize(vCube);
g_CoverInfo.QCostBefore += ComputeQCost(vCube);
}
ABC_FREE( s_Level2Var );
ABC_FREE( s_LevelValues );
assert ( g_CoverInfo.nCubesInUse + g_CoverInfo.nCubesFree == g_CoverInfo.nCubesAlloc );
}
/**Function*************************************************************
Synopsis [Performs heuristic minimization of ESOPs.]
Description [Returns 1 on success, 0 on failure.]
SideEffects []
SeeAlso []
***********************************************************************/
int Exorcism( Vec_Wec_t * vEsop, int nIns, int nOuts, char * pFileNameOut )
{
abctime clk1;
int RemainderBits;
int TotalWords;
int MemTemp, MemTotal;
///////////////////////////////////////////////////////////////////////
// STEPS of HEURISTIC ESOP MINIMIZATION
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// STEP 1: determine the size of the starting cover
///////////////////////////////////////////////////////////////////////
assert( nIns > 0 );
// inputs
RemainderBits = (nIns*2)%(sizeof(unsigned)*8);
TotalWords = (nIns*2)/(sizeof(unsigned)*8) + (RemainderBits > 0);
g_CoverInfo.nVarsIn = nIns;
g_CoverInfo.nWordsIn = TotalWords;
// outputs
RemainderBits = (nOuts)%(sizeof(unsigned)*8);
TotalWords = (nOuts)/(sizeof(unsigned)*8) + (RemainderBits > 0);
g_CoverInfo.nVarsOut = nOuts;
g_CoverInfo.nWordsOut = TotalWords;
g_CoverInfo.cIDs = 1;
// cubes
clk1 = Abc_Clock();
// g_CoverInfo.nCubesBefore = CountTermsInPseudoKroneckerCover( g_Func.dd, nOuts );
g_CoverInfo.nCubesBefore = Vec_WecSize(vEsop);
g_CoverInfo.TimeStart = Abc_Clock() - clk1;
if ( g_CoverInfo.Verbosity )
{
printf( "Starting cover generation time is %.2f sec\n", TICKS_TO_SECONDS(g_CoverInfo.TimeStart) );
printf( "The number of cubes in the starting cover is %d\n", g_CoverInfo.nCubesBefore );
}
if ( g_CoverInfo.nCubesBefore > g_CoverInfo.nCubesMax )
{
printf( "\nThe size of the starting cover is more than %d cubes. Quitting...\n", g_CoverInfo.nCubesMax );
return 0;
}
///////////////////////////////////////////////////////////////////////
// STEP 2: prepare internal data structures
///////////////////////////////////////////////////////////////////////
g_CoverInfo.nCubesAlloc = g_CoverInfo.nCubesBefore + ADDITIONAL_CUBES;
// allocate cube cover
MemTotal = 0;
MemTemp = AllocateCover( g_CoverInfo.nCubesAlloc, g_CoverInfo.nWordsIn, g_CoverInfo.nWordsOut );
if ( MemTemp == 0 )
{
printf( "Unexpected memory allocation problem. Quitting...\n" );
return 0;
}
else
MemTotal += MemTemp;
// allocate cube sets
MemTemp = AllocateCubeSets( g_CoverInfo.nVarsIn, g_CoverInfo.nVarsOut );
if ( MemTemp == 0 )
{
printf( "Unexpected memory allocation problem. Quitting...\n" );
return 0;
}
else
MemTotal += MemTemp;
// allocate adjacency queques
MemTemp = AllocateQueques( g_CoverInfo.nCubesAlloc*g_CoverInfo.nCubesAlloc/CUBE_PAIR_FACTOR );
if ( MemTemp == 0 )
{
printf( "Unexpected memory allocation problem. Quitting...\n" );
return 0;
}
else
MemTotal += MemTemp;
if ( g_CoverInfo.Verbosity )
printf( "Dynamically allocated memory is %dK\n", MemTotal/1000 );
///////////////////////////////////////////////////////////////////////
// STEP 3: write the cube cover into the allocated storage
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
clk1 = Abc_Clock();
if ( g_CoverInfo.Verbosity )
printf( "Generating the starting cover...\n" );
AddCubesToStartingCover( vEsop );
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// STEP 4: iteratively improve the cover
///////////////////////////////////////////////////////////////////////
if ( g_CoverInfo.Verbosity )
printf( "Performing minimization...\n" );
clk1 = Abc_Clock();
ReduceEsopCover();
g_CoverInfo.TimeMin = Abc_Clock() - clk1;
// g_Func.TimeMin = (float)(Abc_Clock() - clk1)/(float)(CLOCKS_PER_SEC);
if ( g_CoverInfo.Verbosity )
{
printf( "\nMinimization time is %.2f sec\n", TICKS_TO_SECONDS(g_CoverInfo.TimeMin) );
printf( "\nThe number of cubes after minimization is %d\n", g_CoverInfo.nCubesInUse );
}
///////////////////////////////////////////////////////////////////////
// STEP 5: save the cover into file
///////////////////////////////////////////////////////////////////////
// if option is MULTI_OUTPUT, the output is written into the output file;
// if option is SINGLE_NODE, the output is added to the input file
// and written into the output file; in this case, the minimized nodes is
// also stored in the temporary file "temp.blif" for verification
// create the file name and write the output
{
char Buffer[1000];
sprintf( Buffer, "%s", pFileNameOut ? pFileNameOut : "temp.esop" );
WriteResultIntoFile( Buffer );
if ( g_CoverInfo.Verbosity )
printf( "Minimized cover has been written into file <%s>\n", Buffer );
}
///////////////////////////////////////////////////////////////////////
// STEP 6: delocate memory
///////////////////////////////////////////////////////////////////////
DelocateCubeSets();
DelocateCover();
DelocateQueques();
// return success
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_ExorcismMain( Vec_Wec_t * vEsop, int nIns, int nOuts, char * pFileNameOut, int Quality, int Verbosity, int nCubesMax, int fUseQCost )
{
memset( &g_CoverInfo, 0, sizeof(cinfo) );
g_CoverInfo.Quality = Quality;
g_CoverInfo.Verbosity = Verbosity;
g_CoverInfo.nCubesMax = nCubesMax;
g_CoverInfo.fUseQCost = fUseQCost;
if ( fUseQCost )
s_fDecreaseLiterals = 1;
if ( g_CoverInfo.Verbosity )
{
printf( "\nEXORCISM, Ver.4.7: Exclusive Sum-of-Product Minimizer\n" );
printf( "by Alan Mishchenko, Portland State University, July-September 2000\n\n" );
printf( "Incoming ESOP has %d inputs, %d outputs, and %d cubes.\n", nIns, nOuts, Vec_WecSize(vEsop) );
}
PrepareBitSetModule();
if ( Exorcism( vEsop, nIns, nOuts, pFileNameOut ) == 0 )
{
printf( "Something went wrong when minimizing the cover\n" );
return 0;
}
return 1;
}
///////////////////////////////////////////////////////////////////
//////////// End of File /////////////////
///////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END