mirror of https://github.com/YosysHQ/abc.git
354 lines
12 KiB
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 ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|