/**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" #include "misc/extra/extraBdd.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// 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 ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END