mirror of
https://github.com/YosysHQ/abc.git
synced 2026-09-02 23:58:27 +02:00
205 lines
5.9 KiB
C
205 lines
5.9 KiB
C
/**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
|
|
|