/**CFile**************************************************************** FileName [fpgaTruth.c] PackageName [MVSIS 1.3: Multi-valued logic synthesis system.] Synopsis [Technology mapping for variable-size-LUT FPGAs.] Author [MVSIS Group] Affiliation [UC Berkeley] Date [Ver. 2.0. Started - August 18, 2004.] Revision [$Id: fpgaTruth.c,v 1.4 2005/01/23 06:59:42 alanmi Exp $] ***********************************************************************/ #include "fpgaInt.h" #include "bdd/cudd/cudd.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Recursively derives the truth table for the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ DdNode * Fpga_TruthsCutBdd_rec( DdManager * dd, Fpga_Cut_t * pCut, Fpga_NodeVec_t * vVisited ) { DdNode * bFunc, * bFunc0, * bFunc1; assert( !Fpga_IsComplement(pCut) ); // if the cut is visited, return the result if ( pCut->uSign ) return (DdNode *)(ABC_PTRUINT_T)pCut->uSign; // compute the functions of the children bFunc0 = Fpga_TruthsCutBdd_rec( dd, Fpga_CutRegular(pCut->pOne), vVisited ); Cudd_Ref( bFunc0 ); bFunc0 = Cudd_NotCond( bFunc0, Fpga_CutIsComplement(pCut->pOne) ); bFunc1 = Fpga_TruthsCutBdd_rec( dd, Fpga_CutRegular(pCut->pTwo), vVisited ); Cudd_Ref( bFunc1 ); bFunc1 = Cudd_NotCond( bFunc1, Fpga_CutIsComplement(pCut->pTwo) ); // get the function of the cut bFunc = Cudd_bddAnd( dd, bFunc0, bFunc1 ); Cudd_Ref( bFunc ); bFunc = Cudd_NotCond( bFunc, pCut->Phase ); Cudd_RecursiveDeref( dd, bFunc0 ); Cudd_RecursiveDeref( dd, bFunc1 ); assert( pCut->uSign == 0 ); pCut->uSign = (unsigned)(ABC_PTRUINT_T)bFunc; // add this cut to the visited list Fpga_NodeVecPush( vVisited, (Fpga_Node_t *)pCut ); return bFunc; } /**Function************************************************************* Synopsis [Derives the truth table for one cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void * Fpga_TruthsCutBdd( void * dd, Fpga_Cut_t * pCut ) { Fpga_NodeVec_t * vVisited; DdNode * bFunc; int i; assert( pCut->nLeaves > 1 ); // set the leaf variables for ( i = 0; i < pCut->nLeaves; i++ ) pCut->ppLeaves[i]->pCuts->uSign = (unsigned)(ABC_PTRUINT_T)Cudd_bddIthVar( (DdManager *)dd, i ); // recursively compute the function vVisited = Fpga_NodeVecAlloc( 10 ); bFunc = Fpga_TruthsCutBdd_rec( (DdManager *)dd, pCut, vVisited ); Cudd_Ref( bFunc ); // clean the intermediate BDDs for ( i = 0; i < pCut->nLeaves; i++ ) pCut->ppLeaves[i]->pCuts->uSign = 0; for ( i = 0; i < vVisited->nSize; i++ ) { pCut = (Fpga_Cut_t *)vVisited->pArray[i]; Cudd_RecursiveDeref( (DdManager *)dd, (DdNode*)(ABC_PTRUINT_T)pCut->uSign ); pCut->uSign = 0; } // printf( "%d ", vVisited->nSize ); Fpga_NodeVecFree( vVisited ); Cudd_Deref( bFunc ); return bFunc; } /**Function************************************************************* Synopsis [Recursively derives the truth table for the cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Fpga_CutVolume_rec( Fpga_Cut_t * pCut, Fpga_NodeVec_t * vVisited ) { assert( !Fpga_IsComplement(pCut) ); if ( pCut->fMark ) return; pCut->fMark = 1; Fpga_CutVolume_rec( Fpga_CutRegular(pCut->pOne), vVisited ); Fpga_CutVolume_rec( Fpga_CutRegular(pCut->pTwo), vVisited ); Fpga_NodeVecPush( vVisited, (Fpga_Node_t *)pCut ); } /**Function************************************************************* Synopsis [Derives the truth table for one cut.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Fpga_CutVolume( Fpga_Cut_t * pCut ) { Fpga_NodeVec_t * vVisited; int Volume, i; assert( pCut->nLeaves > 1 ); // set the leaf variables for ( i = 0; i < pCut->nLeaves; i++ ) pCut->ppLeaves[i]->pCuts->fMark = 1; // recursively compute the function vVisited = Fpga_NodeVecAlloc( 10 ); Fpga_CutVolume_rec( pCut, vVisited ); // clean the marks for ( i = 0; i < pCut->nLeaves; i++ ) pCut->ppLeaves[i]->pCuts->fMark = 0; for ( i = 0; i < vVisited->nSize; i++ ) { pCut = (Fpga_Cut_t *)vVisited->pArray[i]; pCut->fMark = 0; } Volume = vVisited->nSize; printf( "%d ", Volume ); Fpga_NodeVecFree( vVisited ); return Volume; } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END