abc/src/aig/dar/darTruth.c

354 lines
12 KiB
C

/**CFile****************************************************************
FileName [darTruth.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [DAG-aware AIG rewriting.]
Synopsis [Computes the truth table of a cut.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: darTruth.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "darInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
#if 0
/**Function*************************************************************
Synopsis [Computes truth table of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManCollectCut_rec( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Int_t * vNodes )
{
if ( pNode->fMarkA )
return;
pNode->fMarkA = 1;
assert( Aig_ObjIsAnd(pNode) || Aig_ObjIsExor(pNode) );
Aig_ManCollectCut_rec( p, Aig_ObjFanin0(pNode), vNodes );
Aig_ManCollectCut_rec( p, Aig_ObjFanin1(pNode), vNodes );
Vec_IntPush( vNodes, pNode->Id );
}
/**Function*************************************************************
Synopsis [Computes truth table of the cut.]
Description [Does not modify the array of leaves. Uses array vTruth to store
temporary truth tables. The returned pointer should be used immediately.]
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManCollectCut( Aig_Man_t * p, Aig_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes )
{
int i, Leaf;
// collect and mark the leaves
Vec_IntClear( vNodes );
Vec_IntForEachEntry( vLeaves, Leaf, i )
{
Vec_IntPush( vNodes, Leaf );
Aig_ManObj(p, Leaf)->fMarkA = 1;
}
// collect and mark the nodes
Aig_ManCollectCut_rec( p, pRoot, vNodes );
// clean the nodes
Vec_IntForEachEntry( vNodes, Leaf, i )
Aig_ManObj(p, Leaf)->fMarkA = 0;
}
/**Function*************************************************************
Synopsis [Returns the pointer to the truth table.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned * Aig_ObjGetTruthStore( int ObjNum, Vec_Int_t * vTruth )
{
return ((unsigned *)Vec_IntArray(vTruth)) + 8 * ObjNum;
}
/**Function*************************************************************
Synopsis [Computes truth table of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManCutTruthOne( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Int_t * vTruth, int nWords )
{
unsigned * pTruth, * pTruth0, * pTruth1;
int i;
pTruth = Aig_ObjGetTruthStore( pNode->Level, vTruth );
pTruth0 = Aig_ObjGetTruthStore( Aig_ObjFanin0(pNode)->Level, vTruth );
pTruth1 = Aig_ObjGetTruthStore( Aig_ObjFanin1(pNode)->Level, vTruth );
if ( Aig_ObjIsExor(pNode) )
for ( i = 0; i < nWords; i++ )
pTruth[i] = pTruth0[i] ^ pTruth1[i];
else if ( !Aig_ObjFaninC0(pNode) && !Aig_ObjFaninC1(pNode) )
for ( i = 0; i < nWords; i++ )
pTruth[i] = pTruth0[i] & pTruth1[i];
else if ( !Aig_ObjFaninC0(pNode) && Aig_ObjFaninC1(pNode) )
for ( i = 0; i < nWords; i++ )
pTruth[i] = pTruth0[i] & ~pTruth1[i];
else if ( Aig_ObjFaninC0(pNode) && !Aig_ObjFaninC1(pNode) )
for ( i = 0; i < nWords; i++ )
pTruth[i] = ~pTruth0[i] & pTruth1[i];
else // if ( Aig_ObjFaninC0(pNode) && Aig_ObjFaninC1(pNode) )
for ( i = 0; i < nWords; i++ )
pTruth[i] = ~pTruth0[i] & ~pTruth1[i];
}
/**Function*************************************************************
Synopsis [Computes truth table of the cut.]
Description [Does not modify the array of leaves. Uses array vTruth to store
temporary truth tables. The returned pointer should be used immediately.]
SideEffects []
SeeAlso []
***********************************************************************/
unsigned * Aig_ManCutTruth( Aig_Man_t * p, Aig_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth )
{
static unsigned uTruths[8][8] = { // elementary truth tables
{ 0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA,0xAAAAAAAA },
{ 0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC,0xCCCCCCCC },
{ 0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0,0xF0F0F0F0 },
{ 0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00,0xFF00FF00 },
{ 0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000,0xFFFF0000 },
{ 0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF,0x00000000,0xFFFFFFFF },
{ 0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF },
{ 0x00000000,0x00000000,0x00000000,0x00000000,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }
};
int i, Leaf;
// collect the cut
// Aig_ManCollectCut( p, pRoot, vLeaves, vNodes );
// set the node numbers
Vec_IntForEachEntry( vNodes, Leaf, i )
Aig_ManObj(p, Leaf)->Level = i;
// alloc enough memory
Vec_IntClear( vTruth );
Vec_IntGrow( vTruth, 8 * Vec_IntSize(vNodes) );
// set the elementary truth tables
Vec_IntForEachEntry( vLeaves, Leaf, i )
memcpy( Aig_ObjGetTruthStore(i, vTruth), uTruths[i], 8 * sizeof(unsigned) );
// compute truths for other nodes
Vec_IntForEachEntryStart( vNodes, Leaf, i, Vec_IntSize(vLeaves) )
Aig_ManCutTruthOne( p, Aig_ManObj(p, Leaf), vTruth, 8 );
return Aig_ObjGetTruthStore( pRoot->Level, vTruth );
}
static inline int Kit_TruthWordNum( int nVars ) { return nVars <= 5 ? 1 : (1 << (nVars - 5)); }
static inline void Kit_TruthNot( unsigned * pOut, unsigned * pIn, int nVars )
{
int w;
for ( w = Kit_TruthWordNum(nVars)-1; w >= 0; w-- )
pOut[w] = ~pIn[w];
}
/**Function*************************************************************
Synopsis [Computes the cost based on two ISOPs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManLargeCutEvalIsop( unsigned * pTruth, int nVars, Vec_Int_t * vMemory )
{
extern int Kit_TruthIsop( unsigned * puTruth, int nVars, Vec_Int_t * vMemory, int fTryBoth );
int RetValue, nClauses;
// compute ISOP for the positive phase
RetValue = Kit_TruthIsop( pTruth, nVars, vMemory, 0 );
if ( RetValue == -1 )
return AIG_INFINITY;
assert( RetValue == 0 || RetValue == 1 );
nClauses = Vec_IntSize( vMemory );
// compute ISOP for the negative phase
Kit_TruthNot( pTruth, pTruth, nVars );
RetValue = Kit_TruthIsop( pTruth, nVars, vMemory, 0 );
if ( RetValue == -1 )
return AIG_INFINITY;
Kit_TruthNot( pTruth, pTruth, nVars );
assert( RetValue == 0 || RetValue == 1 );
nClauses += Vec_IntSize( vMemory );
return nClauses;
}
/**Function*************************************************************
Synopsis [Computes truth table of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManLargeCutCollect_rec( Aig_Man_t * p, Aig_Obj_t * pNode, Vec_Int_t * vLeaves, Vec_Int_t * vNodes )
{
if ( Aig_ObjIsTravIdCurrent(p, pNode) )
return;
if ( Aig_ObjIsTravIdPrevious(p, pNode) )
{
Vec_IntPush( vLeaves, pNode->Id );
// Vec_IntPush( vNodes, pNode->Id );
Aig_ObjSetTravIdCurrent( p, pNode );
return;
}
assert( Aig_ObjIsAnd(pNode) || Aig_ObjIsExor(pNode) );
Aig_ObjSetTravIdCurrent( p, pNode );
Aig_ManLargeCutCollect_rec( p, Aig_ObjFanin0(pNode), vLeaves, vNodes );
Aig_ManLargeCutCollect_rec( p, Aig_ObjFanin1(pNode), vLeaves, vNodes );
Vec_IntPush( vNodes, pNode->Id );
}
/**Function*************************************************************
Synopsis [Collect leaves and nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManLargeCutCollect( Aig_Man_t * p, Aig_Obj_t * pRoot, Aig_Cut_t * pCutR, Aig_Cut_t * pCutL, int Leaf,
Vec_Int_t * vLeaves, Vec_Int_t * vNodes )
{
Vec_Int_t * vTemp;
Aig_Obj_t * pObj;
int Node, i;
Aig_ManIncrementTravId( p );
Aig_CutForEachLeaf( p, pCutR, pObj, i )
if ( pObj->Id != Leaf )
Aig_ObjSetTravIdCurrent( p, pObj );
Aig_CutForEachLeaf( p, pCutL, pObj, i )
Aig_ObjSetTravIdCurrent( p, pObj );
// collect the internal nodes and leaves
Aig_ManIncrementTravId( p );
vTemp = Vec_IntAlloc( 100 );
Aig_ManLargeCutCollect_rec( p, pRoot, vLeaves, vTemp );
Vec_IntForEachEntry( vLeaves, Node, i )
Vec_IntPush( vNodes, Node );
Vec_IntForEachEntry( vTemp, Node, i )
Vec_IntPush( vNodes, Node );
Vec_IntFree( vTemp );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManLargeCutEval( Aig_Man_t * p, Aig_Obj_t * pRoot, Aig_Cut_t * pCutR, Aig_Cut_t * pCutL, int Leaf )
{
Vec_Int_t * vLeaves, * vNodes, * vTruth, * vMemory;
unsigned * pTruth;
int RetValue;
// Aig_Obj_t * pObj;
vMemory = Vec_IntAlloc( 1 << 16 );
vTruth = Vec_IntAlloc( 1 << 16 );
vLeaves = Vec_IntAlloc( 100 );
vNodes = Vec_IntAlloc( 100 );
Aig_ManLargeCutCollect( p, pRoot, pCutR, pCutL, Leaf, vLeaves, vNodes );
/*
// collect the nodes
Aig_CutForEachLeaf( p, pCutR, pObj, i )
{
if ( pObj->Id == Leaf )
continue;
if ( pObj->fMarkA )
continue;
pObj->fMarkA = 1;
Vec_IntPush( vLeaves, pObj->Id );
Vec_IntPush( vNodes, pObj->Id );
}
Aig_CutForEachLeaf( p, pCutL, pObj, i )
{
if ( pObj->fMarkA )
continue;
pObj->fMarkA = 1;
Vec_IntPush( vLeaves, pObj->Id );
Vec_IntPush( vNodes, pObj->Id );
}
// collect and mark the nodes
Aig_ManCollectCut_rec( p, pRoot, vNodes );
// clean the nodes
Vec_IntForEachEntry( vNodes, Leaf, i )
Aig_ManObj(p, Leaf)->fMarkA = 0;
*/
pTruth = Aig_ManCutTruth( p, pRoot, vLeaves, vNodes, vTruth );
RetValue = Aig_ManLargeCutEvalIsop( pTruth, Vec_IntSize(vLeaves), vMemory );
Vec_IntFree( vLeaves );
Vec_IntFree( vNodes );
Vec_IntFree( vTruth );
Vec_IntFree( vMemory );
return RetValue;
}
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////