/**CFile**************************************************************** FileName [ifCheck.c] SystemName [ABC: Logic synthesis and verification system.] PackageName [FPGA mapping based on priority cuts.] Synopsis [Sequential mapping.] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - November 21, 2006.] Revision [$Id: ifCheck.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $] ***********************************************************************/ #include "if.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// #ifdef WIN32 typedef unsigned __int64 word; #else typedef unsigned long long word; #endif // elementary truth tables static word Truths6[6] = { 0xAAAAAAAAAAAAAAAA, 0xCCCCCCCCCCCCCCCC, 0xF0F0F0F0F0F0F0F0, 0xFF00FF00FF00FF00, 0xFFFF0000FFFF0000, 0xFFFFFFFF00000000 }; //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Returns 1 if the node Leaf is reachable on the path.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int If_ManCutReach_rec( If_Obj_t * pPath, If_Obj_t * pLeaf ) { if ( pPath == pLeaf ) return 1; if ( pPath->fMark ) return 0; assert( If_ObjIsAnd(pPath) ); if ( If_ManCutReach_rec( If_ObjFanin0(pPath), pLeaf ) ) return 1; if ( If_ManCutReach_rec( If_ObjFanin1(pPath), pLeaf ) ) return 1; return 0; } int If_ManCutReach( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pPath, If_Obj_t * pLeaf ) { If_Obj_t * pTemp; int i, RetValue; If_CutForEachLeaf( p, pCut, pTemp, i ) pTemp->fMark = 1; RetValue = If_ManCutReach_rec( pPath, pLeaf ); If_CutForEachLeaf( p, pCut, pTemp, i ) pTemp->fMark = 0; return RetValue; } /**Function************************************************************* Synopsis [Derive truth table for each cofactor.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int If_ManCutTruthCheck_rec( If_Obj_t * pObj, word * pTruths ) { word T0, T1; if ( pObj->fMark ) return pTruths[If_ObjId(pObj)]; assert( If_ObjIsAnd(pObj) ); T0 = If_ManCutTruthCheck_rec( If_ObjFanin0(pObj), pTruths ); T1 = If_ManCutTruthCheck_rec( If_ObjFanin1(pObj), pTruths ); T0 = If_ObjFaninC0(pObj) ? ~T0 : T0; T1 = If_ObjFaninC1(pObj) ? ~T1 : T1; return T0 & T1; } int If_ManCutTruthCheck( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut, If_Obj_t * pLeaf, int Cof, word * pTruths ) { word Truth; If_Obj_t * pTemp; int i, k = 0; assert( Cof == 0 || Cof == 1 ); If_CutForEachLeaf( p, pCut, pTemp, i ) { assert( pTemp->fMark == 0 ); pTemp->fMark = 1; if ( pLeaf == pTemp ) pTruths[If_ObjId(pTemp)] = (Cof ? ~((word)0) : 0); else pTruths[If_ObjId(pTemp)] = Truths6[k++] ; } assert( k + 1 == If_CutLeaveNum(pCut) ); // compute truth table Truth = If_ManCutTruthCheck_rec( pObj, pTruths ); If_CutForEachLeaf( p, pCut, pTemp, i ) pTemp->fMark = 0; return Truth == 0 || Truth == ~((word)0); } /**Function************************************************************* Synopsis [Checks if cut can be structurally/functionally decomposed.] Description [The decomposition is Fn(a,b,c,...) = F2(a, Fn-1(b,c,...)).] SideEffects [] SeeAlso [] ***********************************************************************/ void If_ManCutCheck( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut ) { static int nDecCalls = 0; static int nDecStruct = 0; static int nDecStruct2 = 0; static int nDecFunction = 0; word * pTruths; If_Obj_t * pLeaf, * pPath; int i; if ( pCut == NULL ) { printf( "DecStr = %9d (%6.2f %%).\n", nDecStruct, 100.0*nDecStruct/nDecCalls ); printf( "DecStr2 = %9d (%6.2f %%).\n", nDecStruct2, 100.0*nDecStruct2/nDecCalls ); printf( "DecFunc = %9d (%6.2f %%).\n", nDecFunction, 100.0*nDecFunction/nDecCalls ); printf( "Total = %9d (%6.2f %%).\n", nDecCalls, 100.0*nDecCalls/nDecCalls ); return; } assert( If_ObjIsAnd(pObj) ); assert( pCut->nLeaves <= 7 ); nDecCalls++; // check structural decomposition If_CutForEachLeaf( p, pCut, pLeaf, i ) if ( pLeaf == If_ObjFanin0(pObj) || pLeaf == If_ObjFanin1(pObj) ) break; if ( i < If_CutLeaveNum(pCut) ) { pPath = (pLeaf == If_ObjFanin0(pObj)) ? If_ObjFanin1(pObj) : If_ObjFanin0(pObj); if ( !If_ManCutReach( p, pCut, pPath, pLeaf ) ) { nDecStruct++; // nDecFunction++; // return; } else nDecStruct2++; } // check functional decomposition pTruths = malloc( sizeof(word) * If_ManObjNum(p) ); If_CutForEachLeaf( p, pCut, pLeaf, i ) { if ( If_ManCutTruthCheck( p, pObj, pCut, pLeaf, 0, pTruths ) ) { nDecFunction++; break; } if ( If_ManCutTruthCheck( p, pObj, pCut, pLeaf, 1, pTruths ) ) { nDecFunction++; break; } } free( pTruths ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END