blob: 2da389dabd6b60b317f91fe12cc0333852aa4718 [file] [log] [blame]
/**CFile****************************************************************
FileName [abcEspresso.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Procedures to minimize SOPs using Espresso.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcEspresso.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "base/abc/abc.h"
#include "misc/espresso/espresso.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static void Abc_NodeEspresso( Abc_Obj_t * pNode );
static pset_family Abc_SopToEspresso( char * pSop );
static char * Abc_SopFromEspresso( Extra_MmFlex_t * pMan, pset_family Cover );
static pset_family Abc_EspressoMinimize( pset_family pOnset, pset_family pDcset );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Minimizes SOP representations using Espresso.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkEspresso( Abc_Ntk_t * pNtk, int fVerbose )
{
Abc_Obj_t * pNode;
int i;
assert( Abc_NtkIsLogic(pNtk) );
// convert the network to have SOPs
if ( Abc_NtkHasMapping(pNtk) )
Abc_NtkMapToSop(pNtk);
else if ( Abc_NtkHasBdd(pNtk) )
{
if ( !Abc_NtkBddToSop(pNtk, -1, ABC_INFINITY) )
{
printf( "Abc_NtkEspresso(): Converting to SOPs has failed.\n" );
return;
}
}
// minimize SOPs of all nodes
Abc_NtkForEachNode( pNtk, pNode, i )
if ( i ) Abc_NodeEspresso( pNode );
}
/**Function*************************************************************
Synopsis [Minimizes SOP representation of one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NodeEspresso( Abc_Obj_t * pNode )
{
extern void define_cube_size( int n );
pset_family Cover;
int fCompl;
assert( Abc_ObjIsNode(pNode) );
// define the cube for this node
define_cube_size( Abc_ObjFaninNum(pNode) );
// create the Espresso cover
fCompl = Abc_SopIsComplement( pNode->pData );
Cover = Abc_SopToEspresso( pNode->pData );
// perform minimization
Cover = Abc_EspressoMinimize( Cover, NULL ); // deletes also cover
// convert back onto the node's SOP representation
pNode->pData = Abc_SopFromEspresso( pNode->pNtk->pManFunc, Cover );
if ( fCompl ) Abc_SopComplement( pNode->pData );
sf_free(Cover);
}
/**Function*************************************************************
Synopsis [Converts SOP in ABC into SOP representation in Espresso.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
pset_family Abc_SopToEspresso( char * pSop )
{
char * pCube;
pset_family Cover;
pset set;
int nCubes, nVars, Value, v;
if ( pSop == NULL )
return NULL;
nVars = Abc_SopGetVarNum(pSop);
nCubes = Abc_SopGetCubeNum(pSop);
assert( cube.size == 2 * nVars );
if ( Abc_SopIsConst0(pSop) )
{
Cover = sf_new(0, cube.size);
return Cover;
}
if ( Abc_SopIsConst1(pSop) )
{
Cover = sf_new(1, cube.size);
set = GETSET(Cover, Cover->count++);
set_copy( set, cube.fullset );
return Cover;
}
// create the cover
Cover = sf_new(nCubes, cube.size);
// fill in the cubes
Abc_SopForEachCube( pSop, nVars, pCube )
{
set = GETSET(Cover, Cover->count++);
set_copy( set, cube.fullset );
Abc_CubeForEachVar( pCube, Value, v )
{
if ( Value == '0' )
set_remove(set, 2*v+1);
else if ( Value == '1' )
set_remove(set, 2*v);
}
}
return Cover;
}
/**Function*************************************************************
Synopsis [Converts SOP representation in Espresso into SOP in ABC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
char * Abc_SopFromEspresso( Extra_MmFlex_t * pMan, pset_family Cover )
{
pset set;
char * pSop, * pCube;
int Lit, nVars, nCubes, i, k;
nVars = Cover->sf_size/2;
nCubes = Cover->count;
pSop = Abc_SopStart( pMan, nCubes, nVars );
// go through the cubes
i = 0;
Abc_SopForEachCube( pSop, nVars, pCube )
{
set = GETSET(Cover, i++);
for ( k = 0; k < nVars; k++ )
{
Lit = GETINPUT(set, k);
if ( Lit == ZERO )
pCube[k] = '0';
else if ( Lit == ONE )
pCube[k] = '1';
}
}
return pSop;
}
/**Function*************************************************************
Synopsis [Minimizes the cover using Espresso.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
pset_family Abc_EspressoMinimize( pset_family pOnset, pset_family pDcset )
{
pset_family pOffset;
int fNewDcset, i;
int fSimple = 0;
int fSparse = 0;
if ( fSimple )
{
for ( i = 0; i < cube.num_vars; i++ )
pOnset = d1merge( pOnset, i );
pOnset = sf_contain( pOnset );
return pOnset;
}
// create the dcset
fNewDcset = (pDcset == NULL);
if ( pDcset == NULL )
pDcset = sf_new( 1, cube.size );
pDcset->wsize = pOnset->wsize;
pDcset->sf_size = pOnset->sf_size;
// derive the offset
if ( pDcset->sf_size == 0 || pDcset->count == 0 )
pOffset = complement(cube1list(pOnset));
else
pOffset = complement(cube2list(pOnset, pDcset));
// perform minimization
skip_make_sparse = !fSparse;
pOnset = espresso( pOnset, pDcset, pOffset );
// free covers
sf_free( pOffset );
if ( fNewDcset )
sf_free( pDcset );
return pOnset;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END