blob: 317b6ffd5bd1e35ccbfac3477f941bfda159d13c [file] [log] [blame]
/**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