blob: eb71b9cd261f1910b12ce319434efc63f5c6e28b [file] [log] [blame]
/**CFile****************************************************************
FileName [abcMv.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Network and node package.]
Synopsis [Multi-valued decomposition.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: abcMv.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "base/abc/abc.h"
#ifdef ABC_USE_CUDD
#include "bdd/extrab/extraBdd.h"
#endif
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#ifdef ABC_USE_CUDD
typedef struct Mv_Man_t_ Mv_Man_t;
struct Mv_Man_t_
{
int nInputs; // the number of 4-valued input variables
int nFuncs; // the number of 4-valued functions
DdManager * dd; // representation of functions
DdNode * bValues[15][4]; // representation of i-sets
DdNode * bValueDcs[15][4]; // representation of i-sets don't-cares
DdNode * bFuncs[15]; // representation of functions
};
static void Abc_MvDecompose( Mv_Man_t * p );
static void Abc_MvPrintStats( Mv_Man_t * p );
static void Abc_MvRead( Mv_Man_t * p );
static void Abc_MvDeref( Mv_Man_t * p );
static DdNode * Abc_MvReadCube( DdManager * dd, char * pLine, int nVars );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_MvExperiment()
{
Mv_Man_t * p;
// get the functions
p = ABC_ALLOC( Mv_Man_t, 1 );
memset( p, 0, sizeof(Mv_Man_t) );
p->dd = Cudd_Init( 32, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
p->nFuncs = 15;
p->nInputs = 9;
Abc_MvRead( p );
// process the functions
Abc_MvPrintStats( p );
// Cudd_ReduceHeap( p->dd, CUDD_REORDER_SYMM_SIFT, 1 );
// Abc_MvPrintStats( p );
// try detecting support reducing bound set
Abc_MvDecompose( p );
// remove the manager
Abc_MvDeref( p );
Extra_StopManager( p->dd );
ABC_FREE( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_MvPrintStats( Mv_Man_t * p )
{
int i, v;
for ( i = 0; i < 15; i++ )
{
printf( "%2d : ", i );
printf( "%3d (%2d) ", Cudd_DagSize(p->bFuncs[i])-1, Cudd_SupportSize(p->dd, p->bFuncs[i]) );
for ( v = 0; v < 4; v++ )
printf( "%d = %3d (%2d) ", v, Cudd_DagSize(p->bValues[i][v])-1, Cudd_SupportSize(p->dd, p->bValues[i][v]) );
printf( "\n" );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
DdNode * Abc_MvReadCube( DdManager * dd, char * pLine, int nVars )
{
DdNode * bCube, * bVar, * bTemp;
int i;
bCube = Cudd_ReadOne(dd); Cudd_Ref( bCube );
for ( i = 0; i < nVars; i++ )
{
if ( pLine[i] == '-' )
continue;
else if ( pLine[i] == '0' ) // 0
bVar = Cudd_Not( Cudd_bddIthVar(dd, 29-i) );
else if ( pLine[i] == '1' ) // 1
bVar = Cudd_bddIthVar(dd, 29-i);
else assert(0);
bCube = Cudd_bddAnd( dd, bTemp = bCube, bVar ); Cudd_Ref( bCube );
Cudd_RecursiveDeref( dd, bTemp );
}
Cudd_Deref( bCube );
return bCube;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_MvRead( Mv_Man_t * p )
{
FILE * pFile;
char Buffer[1000], * pLine;
DdNode * bCube, * bTemp, * bProd, * bVar0, * bVar1, * bCubeSum;
int i, v;
// start the cube
bCubeSum = Cudd_ReadLogicZero(p->dd); Cudd_Ref( bCubeSum );
// start the values
for ( i = 0; i < 15; i++ )
for ( v = 0; v < 4; v++ )
{
p->bValues[i][v] = Cudd_ReadLogicZero(p->dd); Cudd_Ref( p->bValues[i][v] );
p->bValueDcs[i][v] = Cudd_ReadLogicZero(p->dd); Cudd_Ref( p->bValueDcs[i][v] );
}
// read the file
pFile = fopen( "input.pla", "r" );
while ( fgets( Buffer, 1000, pFile ) )
{
if ( Buffer[0] == '#' )
continue;
if ( Buffer[0] == '.' )
{
if ( Buffer[1] == 'e' )
break;
continue;
}
// get the cube
bCube = Abc_MvReadCube( p->dd, Buffer, 18 ); Cudd_Ref( bCube );
// add it to the values of the output functions
pLine = Buffer + 19;
for ( i = 0; i < 15; i++ )
{
if ( pLine[2*i] == '-' && pLine[2*i+1] == '-' )
{
for ( v = 0; v < 4; v++ )
{
p->bValueDcs[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValueDcs[i][v], bCube ); Cudd_Ref( p->bValueDcs[i][v] );
Cudd_RecursiveDeref( p->dd, bTemp );
}
continue;
}
else if ( pLine[2*i] == '0' && pLine[2*i+1] == '0' ) // 0
v = 0;
else if ( pLine[2*i] == '1' && pLine[2*i+1] == '0' ) // 1
v = 1;
else if ( pLine[2*i] == '0' && pLine[2*i+1] == '1' ) // 2
v = 2;
else if ( pLine[2*i] == '1' && pLine[2*i+1] == '1' ) // 3
v = 3;
else assert( 0 );
// add the value
p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], bCube ); Cudd_Ref( p->bValues[i][v] );
Cudd_RecursiveDeref( p->dd, bTemp );
}
// add the cube
bCubeSum = Cudd_bddOr( p->dd, bTemp = bCubeSum, bCube ); Cudd_Ref( bCubeSum );
Cudd_RecursiveDeref( p->dd, bTemp );
Cudd_RecursiveDeref( p->dd, bCube );
}
// add the complement of the domain to all values
for ( i = 0; i < 15; i++ )
for ( v = 0; v < 4; v++ )
{
if ( p->bValues[i][v] == Cudd_Not(Cudd_ReadOne(p->dd)) )
continue;
p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], p->bValueDcs[i][v] ); Cudd_Ref( p->bValues[i][v] );
Cudd_RecursiveDeref( p->dd, bTemp );
p->bValues[i][v] = Cudd_bddOr( p->dd, bTemp = p->bValues[i][v], Cudd_Not(bCubeSum) ); Cudd_Ref( p->bValues[i][v] );
Cudd_RecursiveDeref( p->dd, bTemp );
}
printf( "Domain = %5.2f %%.\n", 100.0*Cudd_CountMinterm(p->dd, bCubeSum, 32)/Cudd_CountMinterm(p->dd, Cudd_ReadOne(p->dd), 32) );
Cudd_RecursiveDeref( p->dd, bCubeSum );
// create each output function
for ( i = 0; i < 15; i++ )
{
p->bFuncs[i] = Cudd_ReadLogicZero(p->dd); Cudd_Ref( p->bFuncs[i] );
for ( v = 0; v < 4; v++ )
{
bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 30), ((v & 1) == 0) );
bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 31), ((v & 2) == 0) );
bCube = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bCube );
bProd = Cudd_bddAnd( p->dd, p->bValues[i][v], bCube ); Cudd_Ref( bProd );
Cudd_RecursiveDeref( p->dd, bCube );
// add the value
p->bFuncs[i] = Cudd_bddOr( p->dd, bTemp = p->bFuncs[i], bProd ); Cudd_Ref( p->bFuncs[i] );
Cudd_RecursiveDeref( p->dd, bTemp );
Cudd_RecursiveDeref( p->dd, bProd );
}
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_MvDeref( Mv_Man_t * p )
{
int i, v;
for ( i = 0; i < 15; i++ )
for ( v = 0; v < 4; v++ )
{
Cudd_RecursiveDeref( p->dd, p->bValues[i][v] );
Cudd_RecursiveDeref( p->dd, p->bValueDcs[i][v] );
}
for ( i = 0; i < 15; i++ )
Cudd_RecursiveDeref( p->dd, p->bFuncs[i] );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_MvDecompose( Mv_Man_t * p )
{
DdNode * bCofs[16], * bVarCube1, * bVarCube2, * bVarCube, * bCube, * bVar0, * bVar1;//, * bRes;
int k, i1, i2, v1, v2;//, c1, c2, Counter;
bVar0 = Cudd_bddIthVar(p->dd, 30);
bVar1 = Cudd_bddIthVar(p->dd, 31);
bCube = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bCube );
for ( k = 0; k < p->nFuncs; k++ )
{
printf( "FUNCTION %d\n", k );
for ( i1 = 0; i1 < p->nFuncs; i1++ )
for ( i2 = i1+1; i2 < p->nFuncs; i2++ )
{
Vec_Ptr_t * vCofs;
for ( v1 = 0; v1 < 4; v1++ )
{
bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i1 ), ((v1 & 1) == 0) );
bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i1-1), ((v1 & 2) == 0) );
bVarCube1 = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bVarCube1 );
for ( v2 = 0; v2 < 4; v2++ )
{
bVar0 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i2 ), ((v2 & 1) == 0) );
bVar1 = Cudd_NotCond( Cudd_bddIthVar(p->dd, 29-2*i2-1), ((v2 & 2) == 0) );
bVarCube2 = Cudd_bddAnd( p->dd, bVar0, bVar1 ); Cudd_Ref( bVarCube2 );
bVarCube = Cudd_bddAnd( p->dd, bVarCube1, bVarCube2 ); Cudd_Ref( bVarCube );
bCofs[v1 * 4 + v2] = Cudd_Cofactor( p->dd, p->bFuncs[k], bVarCube ); Cudd_Ref( bCofs[v1 * 4 + v2] );
Cudd_RecursiveDeref( p->dd, bVarCube );
Cudd_RecursiveDeref( p->dd, bVarCube2 );
}
Cudd_RecursiveDeref( p->dd, bVarCube1 );
}
/*
// check the compatibility of cofactors
Counter = 0;
for ( c1 = 0; c1 < 16; c1++ )
{
for ( c2 = 0; c2 <= c1; c2++ )
printf( " " );
for ( c2 = c1+1; c2 < 16; c2++ )
{
bRes = Cudd_bddAndAbstract( p->dd, bCofs[c1], bCofs[c2], bCube ); Cudd_Ref( bRes );
if ( bRes == Cudd_ReadOne(p->dd) )
{
printf( "+" );
Counter++;
}
else
{
printf( " " );
}
Cudd_RecursiveDeref( p->dd, bRes );
}
printf( "\n" );
}
*/
vCofs = Vec_PtrAlloc( 16 );
for ( v1 = 0; v1 < 4; v1++ )
for ( v2 = 0; v2 < 4; v2++ )
Vec_PtrPushUnique( vCofs, bCofs[v1 * 4 + v2] );
printf( "%d ", Vec_PtrSize(vCofs) );
Vec_PtrFree( vCofs );
// free the cofactors
for ( v1 = 0; v1 < 4; v1++ )
for ( v2 = 0; v2 < 4; v2++ )
Cudd_RecursiveDeref( p->dd, bCofs[v1 * 4 + v2] );
printf( "\n" );
// printf( "%2d, %2d : %3d\n", i1, i2, Counter );
}
}
Cudd_RecursiveDeref( p->dd, bCube );
}
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END