blob: 506da2e5cb52fc45a721e84e292d8985b183f82f [file] [log] [blame]
/**CFile****************************************************************
FileName [kitIsop.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Computation kit.]
Synopsis [ISOP computation based on Morreale's algorithm.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - Dec 6, 2006.]
Revision [$Id: kitIsop.c,v 1.00 2006/12/06 00:00:00 alanmi Exp $]
***********************************************************************/
#include "kit.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// ISOP computation fails if intermediate memory usage exceed this limit
#define KIT_ISOP_MEM_LIMIT (1<<20)
// static procedures to compute ISOP
static unsigned * Kit_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore );
static unsigned Kit_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes ISOP from TT.]
Description [Returns the cover in vMemory. Uses the rest of array in vMemory
as an intermediate memory storage. Returns the cover with -1 cubes, if the
the computation exceeded the memory limit (KIT_ISOP_MEM_LIMIT words of
intermediate data).]
SideEffects []
SeeAlso []
***********************************************************************/
int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth )
{
Kit_Sop_t cRes, * pcRes = &cRes;
Kit_Sop_t cRes2, * pcRes2 = &cRes2;
unsigned * pResult;
int RetValue = 0;
assert( nVars >= 0 && nVars <= 16 );
// if nVars < 5, make sure it does not depend on those vars
// for ( i = nVars; i < 5; i++ )
// assert( !Kit_TruthVarInSupport(puTruth, 5, i) );
// prepare memory manager
Vec_IntClear( vMemory );
Vec_IntGrow( vMemory, KIT_ISOP_MEM_LIMIT );
// compute ISOP for the direct polarity
pResult = Kit_TruthIsop_rec( puTruth, puTruth, nVars, pcRes, vMemory );
if ( pcRes->nCubes == -1 )
{
vMemory->nSize = -1;
return -1;
}
assert( Kit_TruthIsEqual( puTruth, pResult, nVars ) );
if ( pcRes->nCubes == 0 || (pcRes->nCubes == 1 && pcRes->pCubes[0] == 0) )
{
vMemory->pArray[0] = 0;
Vec_IntShrink( vMemory, pcRes->nCubes );
return 0;
}
if ( fTryBoth )
{
// compute ISOP for the complemented polarity
Kit_TruthNot( puTruth, puTruth, nVars );
pResult = Kit_TruthIsop_rec( puTruth, puTruth, nVars, pcRes2, vMemory );
if ( pcRes2->nCubes >= 0 )
{
assert( Kit_TruthIsEqual( puTruth, pResult, nVars ) );
if ( pcRes->nCubes > pcRes2->nCubes || (pcRes->nCubes == pcRes2->nCubes && pcRes->nLits > pcRes2->nLits) )
{
RetValue = 1;
pcRes = pcRes2;
}
}
Kit_TruthNot( puTruth, puTruth, nVars );
}
// printf( "%d ", vMemory->nSize );
// move the cover representation to the beginning of the memory buffer
memmove( vMemory->pArray, pcRes->pCubes, pcRes->nCubes * sizeof(unsigned) );
Vec_IntShrink( vMemory, pcRes->nCubes );
return RetValue;
}
void Kit_TruthIsopPrintCover( Vec_Int_t * vCover, int nVars, int fCompl )
{
int i, k, Entry, Literal;
if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover, 0) == 0) )
{
printf( "Constant %d\n", Vec_IntSize(vCover) );
return;
}
Vec_IntForEachEntry( vCover, Entry, i )
{
for ( k = 0; k < nVars; k++ )
{
Literal = 3 & (Entry >> (k << 1));
if ( Literal == 1 ) // neg literal
printf( "0" );
else if ( Literal == 2 ) // pos literal
printf( "1" );
else if ( Literal == 0 )
printf( "-" );
else assert( 0 );
}
printf( " %d\n", !fCompl );
}
}
void Kit_TruthIsopPrint( unsigned * puTruth, int nVars, Vec_Int_t * vCover, int fTryBoth )
{
int fCompl = Kit_TruthIsop( puTruth, nVars, vCover, fTryBoth );
Kit_TruthIsopPrintCover( vCover, nVars, fCompl );
}
/**Function*************************************************************
Synopsis [Computes ISOP 6 variables or more.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned * Kit_TruthIsop_rec( unsigned * puOn, unsigned * puOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore )
{
Kit_Sop_t cRes0, cRes1, cRes2;
Kit_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2;
unsigned * puRes0, * puRes1, * puRes2;
unsigned * puOn0, * puOn1, * puOnDc0, * puOnDc1, * pTemp, * pTemp0, * pTemp1;
int i, k, Var, nWords, nWordsAll;
// assert( Kit_TruthIsImply( puOn, puOnDc, nVars ) );
// allocate room for the resulting truth table
nWordsAll = Kit_TruthWordNum( nVars );
pTemp = Vec_IntFetch( vStore, nWordsAll );
if ( pTemp == NULL )
{
pcRes->nCubes = -1;
return NULL;
}
// check for constants
if ( Kit_TruthIsConst0( puOn, nVars ) )
{
pcRes->nLits = 0;
pcRes->nCubes = 0;
pcRes->pCubes = NULL;
Kit_TruthClear( pTemp, nVars );
return pTemp;
}
if ( Kit_TruthIsConst1( puOnDc, nVars ) )
{
pcRes->nLits = 0;
pcRes->nCubes = 1;
pcRes->pCubes = Vec_IntFetch( vStore, 1 );
if ( pcRes->pCubes == NULL )
{
pcRes->nCubes = -1;
return NULL;
}
pcRes->pCubes[0] = 0;
Kit_TruthFill( pTemp, nVars );
return pTemp;
}
assert( nVars > 0 );
// find the topmost var
for ( Var = nVars-1; Var >= 0; Var-- )
if ( Kit_TruthVarInSupport( puOn, nVars, Var ) ||
Kit_TruthVarInSupport( puOnDc, nVars, Var ) )
break;
assert( Var >= 0 );
// consider a simple case when one-word computation can be used
if ( Var < 5 )
{
unsigned uRes = Kit_TruthIsop5_rec( puOn[0], puOnDc[0], Var+1, pcRes, vStore );
for ( i = 0; i < nWordsAll; i++ )
pTemp[i] = uRes;
return pTemp;
}
assert( Var >= 5 );
nWords = Kit_TruthWordNum( Var );
// cofactor
puOn0 = puOn; puOn1 = puOn + nWords;
puOnDc0 = puOnDc; puOnDc1 = puOnDc + nWords;
pTemp0 = pTemp; pTemp1 = pTemp + nWords;
// solve for cofactors
Kit_TruthSharp( pTemp0, puOn0, puOnDc1, Var );
puRes0 = Kit_TruthIsop_rec( pTemp0, puOnDc0, Var, pcRes0, vStore );
if ( pcRes0->nCubes == -1 )
{
pcRes->nCubes = -1;
return NULL;
}
Kit_TruthSharp( pTemp1, puOn1, puOnDc0, Var );
puRes1 = Kit_TruthIsop_rec( pTemp1, puOnDc1, Var, pcRes1, vStore );
if ( pcRes1->nCubes == -1 )
{
pcRes->nCubes = -1;
return NULL;
}
Kit_TruthSharp( pTemp0, puOn0, puRes0, Var );
Kit_TruthSharp( pTemp1, puOn1, puRes1, Var );
Kit_TruthOr( pTemp0, pTemp0, pTemp1, Var );
Kit_TruthAnd( pTemp1, puOnDc0, puOnDc1, Var );
puRes2 = Kit_TruthIsop_rec( pTemp0, pTemp1, Var, pcRes2, vStore );
if ( pcRes2->nCubes == -1 )
{
pcRes->nCubes = -1;
return NULL;
}
// create the resulting cover
pcRes->nLits = pcRes0->nLits + pcRes1->nLits + pcRes2->nLits + pcRes0->nCubes + pcRes1->nCubes;
pcRes->nCubes = pcRes0->nCubes + pcRes1->nCubes + pcRes2->nCubes;
pcRes->pCubes = Vec_IntFetch( vStore, pcRes->nCubes );
if ( pcRes->pCubes == NULL )
{
pcRes->nCubes = -1;
return NULL;
}
k = 0;
for ( i = 0; i < pcRes0->nCubes; i++ )
pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+0));
for ( i = 0; i < pcRes1->nCubes; i++ )
pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+1));
for ( i = 0; i < pcRes2->nCubes; i++ )
pcRes->pCubes[k++] = pcRes2->pCubes[i];
assert( k == pcRes->nCubes );
// create the resulting truth table
Kit_TruthOr( pTemp0, puRes0, puRes2, Var );
Kit_TruthOr( pTemp1, puRes1, puRes2, Var );
// copy the table if needed
nWords <<= 1;
for ( i = 1; i < nWordsAll/nWords; i++ )
for ( k = 0; k < nWords; k++ )
pTemp[i*nWords + k] = pTemp[k];
// verify in the end
// assert( Kit_TruthIsImply( puOn, pTemp, nVars ) );
// assert( Kit_TruthIsImply( pTemp, puOnDc, nVars ) );
return pTemp;
}
/**Function*************************************************************
Synopsis [Computes ISOP for 5 variables or less.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned Kit_TruthIsop5_rec( unsigned uOn, unsigned uOnDc, int nVars, Kit_Sop_t * pcRes, Vec_Int_t * vStore )
{
unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
Kit_Sop_t cRes0, cRes1, cRes2;
Kit_Sop_t * pcRes0 = &cRes0, * pcRes1 = &cRes1, * pcRes2 = &cRes2;
unsigned uOn0, uOn1, uOnDc0, uOnDc1, uRes0, uRes1, uRes2;
int i, k, Var;
assert( nVars <= 5 );
assert( (uOn & ~uOnDc) == 0 );
if ( uOn == 0 )
{
pcRes->nLits = 0;
pcRes->nCubes = 0;
pcRes->pCubes = NULL;
return 0;
}
if ( uOnDc == 0xFFFFFFFF )
{
pcRes->nLits = 0;
pcRes->nCubes = 1;
pcRes->pCubes = Vec_IntFetch( vStore, 1 );
if ( pcRes->pCubes == NULL )
{
pcRes->nCubes = -1;
return 0;
}
pcRes->pCubes[0] = 0;
return 0xFFFFFFFF;
}
assert( nVars > 0 );
// find the topmost var
for ( Var = nVars-1; Var >= 0; Var-- )
if ( Kit_TruthVarInSupport( &uOn, 5, Var ) ||
Kit_TruthVarInSupport( &uOnDc, 5, Var ) )
break;
assert( Var >= 0 );
// cofactor
uOn0 = uOn1 = uOn;
uOnDc0 = uOnDc1 = uOnDc;
Kit_TruthCofactor0( &uOn0, Var + 1, Var );
Kit_TruthCofactor1( &uOn1, Var + 1, Var );
Kit_TruthCofactor0( &uOnDc0, Var + 1, Var );
Kit_TruthCofactor1( &uOnDc1, Var + 1, Var );
// solve for cofactors
uRes0 = Kit_TruthIsop5_rec( uOn0 & ~uOnDc1, uOnDc0, Var, pcRes0, vStore );
if ( pcRes0->nCubes == -1 )
{
pcRes->nCubes = -1;
return 0;
}
uRes1 = Kit_TruthIsop5_rec( uOn1 & ~uOnDc0, uOnDc1, Var, pcRes1, vStore );
if ( pcRes1->nCubes == -1 )
{
pcRes->nCubes = -1;
return 0;
}
uRes2 = Kit_TruthIsop5_rec( (uOn0 & ~uRes0) | (uOn1 & ~uRes1), uOnDc0 & uOnDc1, Var, pcRes2, vStore );
if ( pcRes2->nCubes == -1 )
{
pcRes->nCubes = -1;
return 0;
}
// create the resulting cover
pcRes->nLits = pcRes0->nLits + pcRes1->nLits + pcRes2->nLits + pcRes0->nCubes + pcRes1->nCubes;
pcRes->nCubes = pcRes0->nCubes + pcRes1->nCubes + pcRes2->nCubes;
pcRes->pCubes = Vec_IntFetch( vStore, pcRes->nCubes );
if ( pcRes->pCubes == NULL )
{
pcRes->nCubes = -1;
return 0;
}
k = 0;
for ( i = 0; i < pcRes0->nCubes; i++ )
pcRes->pCubes[k++] = pcRes0->pCubes[i] | (1 << ((Var<<1)+0));
for ( i = 0; i < pcRes1->nCubes; i++ )
pcRes->pCubes[k++] = pcRes1->pCubes[i] | (1 << ((Var<<1)+1));
for ( i = 0; i < pcRes2->nCubes; i++ )
pcRes->pCubes[k++] = pcRes2->pCubes[i];
assert( k == pcRes->nCubes );
// derive the final truth table
uRes2 |= (uRes0 & ~uMasks[Var]) | (uRes1 & uMasks[Var]);
// assert( (uOn & ~uRes2) == 0 );
// assert( (uRes2 & ~uOnDc) == 0 );
return uRes2;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END