mirror of https://github.com/YosysHQ/abc.git
251 lines
6.7 KiB
C
251 lines
6.7 KiB
C
/**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 "abc.h"
|
|
#include "espresso.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// 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, 0) )
|
|
{
|
|
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 ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|