2017-01-10 10:58:24 +01:00
|
|
|
/**CFile****************************************************************
|
|
|
|
|
|
|
|
|
|
FileName [acecTree.c]
|
|
|
|
|
|
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
|
|
|
|
|
|
PackageName [CEC for arithmetic circuits.]
|
|
|
|
|
|
|
|
|
|
Synopsis [Adder tree construction.]
|
|
|
|
|
|
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
|
|
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
|
|
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
|
|
|
|
|
|
Revision [$Id: acecTree.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "acecInt.h"
|
|
|
|
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// DECLARATIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// FUNCTION DEFINITIONS ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2017-01-11 10:08:23 +01:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
void Acec_BoxFree( Acec_Box_t * pBox )
|
|
|
|
|
{
|
|
|
|
|
Vec_WecFreeP( &pBox->vAdds );
|
|
|
|
|
Vec_WecFreeP( &pBox->vLeafs );
|
|
|
|
|
Vec_WecFreeP( &pBox->vRoots );
|
|
|
|
|
Vec_WecFreeP( &pBox->vLeafLits );
|
|
|
|
|
Vec_WecFreeP( &pBox->vRootLits );
|
|
|
|
|
Vec_WecFreeP( &pBox->vUnique );
|
|
|
|
|
Vec_WecFreeP( &pBox->vShared );
|
|
|
|
|
Vec_BitFreeP( &pBox->vInvHadds );
|
|
|
|
|
ABC_FREE( pBox );
|
|
|
|
|
}
|
|
|
|
|
void Acec_BoxFreeP( Acec_Box_t ** ppBox )
|
|
|
|
|
{
|
|
|
|
|
if ( *ppBox )
|
|
|
|
|
Acec_BoxFree( *ppBox );
|
|
|
|
|
*ppBox = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-10 13:19:02 +01:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Find internal cut points with exactly one adder fanin/fanout.]
|
|
|
|
|
|
|
|
|
|
Description [Returns a map of point into its input/output adder.]
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
void Acec_TreeAddInOutPoint( Vec_Int_t * vMap, int iObj, int iAdd, int fOut )
|
|
|
|
|
{
|
|
|
|
|
int * pPlace = Vec_IntEntryP( vMap, Abc_Var2Lit(iObj, fOut) );
|
|
|
|
|
if ( *pPlace == -1 )
|
|
|
|
|
*pPlace = iAdd;
|
|
|
|
|
else if ( *pPlace >= 0 )
|
|
|
|
|
*pPlace = -2;
|
|
|
|
|
}
|
|
|
|
|
Vec_Int_t * Acec_TreeFindPoints( Gia_Man_t * p, Vec_Int_t * vAdds )
|
|
|
|
|
{
|
|
|
|
|
Vec_Int_t * vMap = Vec_IntStartFull( 2*Gia_ManObjNum(p) );
|
|
|
|
|
int i;
|
|
|
|
|
for ( i = 0; 6*i < Vec_IntSize(vAdds); i++ )
|
|
|
|
|
{
|
|
|
|
|
Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+0), i, 0 );
|
|
|
|
|
Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+1), i, 0 );
|
|
|
|
|
Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+2), i, 0 );
|
|
|
|
|
Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+3), i, 1 );
|
|
|
|
|
Acec_TreeAddInOutPoint( vMap, Vec_IntEntry(vAdds, 6*i+4), i, 1 );
|
|
|
|
|
}
|
|
|
|
|
return vMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Find adder trees as groups of adders connected vis cut-points.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
int Acec_TreeWhichPoint( Vec_Int_t * vAdds, int iAdd, int iObj )
|
|
|
|
|
{
|
|
|
|
|
int k;
|
|
|
|
|
for ( k = 0; k < 5; k++ )
|
|
|
|
|
if ( Vec_IntEntry(vAdds, 6*iAdd+k) == iObj )
|
|
|
|
|
return k;
|
|
|
|
|
assert( 0 );
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
void Acec_TreeFindTrees2_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iAdd, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound )
|
|
|
|
|
{
|
|
|
|
|
extern void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound );
|
|
|
|
|
int k;
|
|
|
|
|
if ( Vec_BitEntry(vFound, iAdd) )
|
|
|
|
|
return;
|
|
|
|
|
Vec_BitWriteEntry( vFound, iAdd, 1 );
|
|
|
|
|
Vec_IntPush( vTree, iAdd );
|
|
|
|
|
Vec_IntPush( vTree, Rank );
|
|
|
|
|
//printf( "Assigning rank %d to (%d:%d).\n", Rank, Vec_IntEntry(vAdds, 6*iAdd+3), Vec_IntEntry(vAdds, 6*iAdd+4) );
|
|
|
|
|
for ( k = 0; k < 5; k++ )
|
|
|
|
|
Acec_TreeFindTrees_rec( vAdds, vMap, Vec_IntEntry(vAdds, 6*iAdd+k), k == 4 ? Rank + 1 : Rank, vTree, vFound );
|
|
|
|
|
}
|
|
|
|
|
void Acec_TreeFindTrees_rec( Vec_Int_t * vAdds, Vec_Int_t * vMap, int iObj, int Rank, Vec_Int_t * vTree, Vec_Bit_t * vFound )
|
|
|
|
|
{
|
|
|
|
|
int In = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 1) );
|
|
|
|
|
int Out = Vec_IntEntry( vMap, Abc_Var2Lit(iObj, 0) );
|
|
|
|
|
if ( In < 0 || Out < 0 )
|
|
|
|
|
return;
|
|
|
|
|
Acec_TreeFindTrees2_rec( vAdds, vMap, In, Acec_TreeWhichPoint(vAdds, In, iObj) == 4 ? Rank-1 : Rank, vTree, vFound );
|
|
|
|
|
Acec_TreeFindTrees2_rec( vAdds, vMap, Out, Rank, vTree, vFound );
|
|
|
|
|
}
|
|
|
|
|
Vec_Wec_t * Acec_TreeFindTrees( Gia_Man_t * p, Vec_Int_t * vAdds )
|
|
|
|
|
{
|
|
|
|
|
Vec_Wec_t * vTrees = Vec_WecAlloc( 10 );
|
|
|
|
|
Vec_Int_t * vMap = Acec_TreeFindPoints( p, vAdds );
|
|
|
|
|
Vec_Bit_t * vFound = Vec_BitStart( Vec_IntSize(vAdds)/6 );
|
|
|
|
|
Vec_Int_t * vTree;
|
|
|
|
|
int i, k, In, Out, Box, Rank, MinRank;
|
|
|
|
|
// go through the cut-points
|
|
|
|
|
Vec_IntForEachEntryDouble( vMap, In, Out, i )
|
|
|
|
|
{
|
|
|
|
|
if ( In < 0 || Out < 0 )
|
|
|
|
|
continue;
|
|
|
|
|
assert( Vec_BitEntry(vFound, In) == Vec_BitEntry(vFound, Out) );
|
|
|
|
|
if ( Vec_BitEntry(vFound, In) )
|
|
|
|
|
continue;
|
|
|
|
|
vTree = Vec_WecPushLevel( vTrees );
|
|
|
|
|
Acec_TreeFindTrees_rec( vAdds, vMap, i/2, 0, vTree, vFound );
|
|
|
|
|
// normalize rank
|
|
|
|
|
MinRank = ABC_INFINITY;
|
|
|
|
|
Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
|
|
|
|
|
MinRank = Abc_MinInt( MinRank, Rank );
|
|
|
|
|
Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
|
|
|
|
|
Vec_IntWriteEntry( vTree, k+1, Rank - MinRank );
|
|
|
|
|
}
|
|
|
|
|
Vec_BitFree( vFound );
|
|
|
|
|
Vec_IntFree( vMap );
|
|
|
|
|
// sort by size
|
|
|
|
|
Vec_WecSort( vTrees, 1 );
|
|
|
|
|
return vTrees;
|
|
|
|
|
}
|
|
|
|
|
void Acec_TreeFindTreesTest( Gia_Man_t * p )
|
|
|
|
|
{
|
|
|
|
|
Vec_Wec_t * vTrees;
|
|
|
|
|
|
|
|
|
|
abctime clk = Abc_Clock();
|
|
|
|
|
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
|
|
|
|
|
int nFadds = Ree_ManCountFadds( vAdds );
|
|
|
|
|
printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds );
|
|
|
|
|
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
|
|
|
|
|
|
|
|
|
clk = Abc_Clock();
|
|
|
|
|
vTrees = Acec_TreeFindTrees( p, vAdds );
|
|
|
|
|
printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 );
|
|
|
|
|
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
|
|
|
|
Vec_WecPrint( vTrees, 0 );
|
|
|
|
|
|
|
|
|
|
Vec_WecFree( vTrees );
|
|
|
|
|
Vec_IntFree( vAdds );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Creates leaves and roots.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
int Acec_CreateBoxMaxRank( Vec_Int_t * vTree )
|
|
|
|
|
{
|
|
|
|
|
int k, Box, Rank, MaxRank = 0;
|
|
|
|
|
Vec_IntForEachEntryDouble( vTree, Box, Rank, k )
|
|
|
|
|
MaxRank = Abc_MaxInt( MaxRank, Rank );
|
|
|
|
|
return MaxRank;
|
|
|
|
|
}
|
2017-01-11 07:36:54 +01:00
|
|
|
void Acec_TreeInsOuts( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree, Vec_Wec_t * vBoxes, Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots )
|
2017-01-10 13:19:02 +01:00
|
|
|
{
|
|
|
|
|
Vec_Bit_t * vIsLeaf = Vec_BitStart( Gia_ManObjNum(p) );
|
|
|
|
|
Vec_Bit_t * vIsRoot = Vec_BitStart( Gia_ManObjNum(p) );
|
|
|
|
|
Vec_Int_t * vLevel;
|
|
|
|
|
int i, k, Box, Rank;
|
|
|
|
|
Vec_BitWriteEntry( vIsLeaf, 0, 1 );
|
|
|
|
|
Vec_BitWriteEntry( vIsRoot, 0, 1 );
|
|
|
|
|
Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
|
|
|
|
|
{
|
|
|
|
|
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+0), 1 );
|
|
|
|
|
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+1), 1 );
|
|
|
|
|
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+2), 1 );
|
|
|
|
|
Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+3), 1 );
|
|
|
|
|
Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+4), 1 );
|
|
|
|
|
}
|
|
|
|
|
Vec_IntForEachEntryDouble( vTree, Box, Rank, i )
|
|
|
|
|
{
|
2017-01-11 07:36:54 +01:00
|
|
|
Vec_WecPush( vBoxes, Rank, Box );
|
2017-01-10 13:19:02 +01:00
|
|
|
for ( k = 0; k < 3; k++ )
|
|
|
|
|
{
|
|
|
|
|
if ( Vec_BitEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k) ) )
|
|
|
|
|
continue;
|
|
|
|
|
Vec_BitWriteEntry( vIsRoot, Vec_IntEntry(vAdds, 6*Box+k), 1 );
|
|
|
|
|
Vec_WecPush( vLeaves, Rank, Vec_IntEntry(vAdds, 6*Box+k) );
|
|
|
|
|
}
|
|
|
|
|
for ( k = 3; k < 5; k++ )
|
|
|
|
|
{
|
|
|
|
|
if ( Vec_BitEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k) ) )
|
|
|
|
|
continue;
|
|
|
|
|
Vec_BitWriteEntry( vIsLeaf, Vec_IntEntry(vAdds, 6*Box+k), 1 );
|
|
|
|
|
Vec_WecPush( vRoots, k == 4 ? Rank + 1 : Rank, Abc_Var2Lit(Abc_Var2Lit(Vec_IntEntry(vAdds, 6*Box+k), k==4), Vec_IntEntry(vAdds, 6*Box+2)!=0) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Vec_BitFree( vIsLeaf );
|
|
|
|
|
Vec_BitFree( vIsRoot );
|
|
|
|
|
// sort each level
|
2017-01-11 07:36:54 +01:00
|
|
|
Vec_WecForEachLevel( vBoxes, vLevel, i )
|
|
|
|
|
Vec_IntSort( vLevel, 0 );
|
2017-01-10 13:19:02 +01:00
|
|
|
Vec_WecForEachLevel( vLeaves, vLevel, i )
|
|
|
|
|
Vec_IntSort( vLevel, 0 );
|
|
|
|
|
Vec_WecForEachLevel( vRoots, vLevel, i )
|
|
|
|
|
Vec_IntSort( vLevel, 0 );
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-11 07:36:54 +01:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
|
|
|
|
int Acec_TreeVerifyPhaseOne_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
|
|
|
|
|
{
|
|
|
|
|
int Truth0, Truth1;
|
|
|
|
|
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
|
|
|
|
return pObj->Value;
|
|
|
|
|
Gia_ObjSetTravIdCurrent(p, pObj);
|
|
|
|
|
assert( Gia_ObjIsAnd(pObj) );
|
|
|
|
|
assert( !Gia_ObjIsXor(pObj) );
|
|
|
|
|
Truth0 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin0(pObj) );
|
|
|
|
|
Truth1 = Acec_TreeVerifyPhaseOne_rec( p, Gia_ObjFanin1(pObj) );
|
|
|
|
|
Truth0 = Gia_ObjFaninC0(pObj) ? 0xFF & ~Truth0 : Truth0;
|
|
|
|
|
Truth1 = Gia_ObjFaninC1(pObj) ? 0xFF & ~Truth1 : Truth1;
|
|
|
|
|
return (pObj->Value = Truth0 & Truth1);
|
|
|
|
|
}
|
|
|
|
|
void Acec_TreeVerifyPhaseOne( Gia_Man_t * p, Vec_Int_t * vAdds, int iBox, Vec_Bit_t * vPhase )
|
|
|
|
|
{
|
|
|
|
|
Gia_Obj_t * pObj;
|
|
|
|
|
unsigned TruthXor, TruthMaj, Truths[3] = { 0xAA, 0xCC, 0xF0 };
|
|
|
|
|
int k, iObj, fFadd = Vec_IntEntry(vAdds, 6*iBox+2) > 0;
|
|
|
|
|
|
|
|
|
|
//if ( !fFadd )
|
|
|
|
|
// return;
|
|
|
|
|
|
|
|
|
|
Gia_ManIncrementTravId( p );
|
|
|
|
|
for ( k = 0; k < 3; k++ )
|
|
|
|
|
{
|
|
|
|
|
iObj = Vec_IntEntry( vAdds, 6*iBox+k );
|
|
|
|
|
if ( iObj == 0 )
|
|
|
|
|
continue;
|
|
|
|
|
pObj = Gia_ManObj( p, iObj );
|
|
|
|
|
pObj->Value = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~Truths[k] : Truths[k];
|
|
|
|
|
Gia_ObjSetTravIdCurrent( p, pObj );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
iObj = Vec_IntEntry( vAdds, 6*iBox+3 );
|
|
|
|
|
TruthXor = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) );
|
|
|
|
|
TruthXor = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthXor : TruthXor;
|
|
|
|
|
|
|
|
|
|
iObj = Vec_IntEntry( vAdds, 6*iBox+4 );
|
|
|
|
|
TruthMaj = Acec_TreeVerifyPhaseOne_rec( p, Gia_ManObj(p, iObj) );
|
|
|
|
|
TruthMaj = Vec_BitEntry(vPhase, iObj) ? 0xFF & ~TruthMaj : TruthMaj;
|
|
|
|
|
|
|
|
|
|
if ( fFadd ) // FADD
|
|
|
|
|
{
|
|
|
|
|
if ( TruthXor != 0x96 )
|
|
|
|
|
printf( "Fadd %d sum is wrong.\n", iBox );
|
|
|
|
|
if ( TruthMaj != 0xE8 )
|
|
|
|
|
printf( "Fadd %d carry is wrong.\n", iBox );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if ( TruthXor != 0x66 )
|
|
|
|
|
printf( "Hadd %d sum is wrong.\n", iBox );
|
|
|
|
|
if ( TruthMaj != 0x88 )
|
|
|
|
|
printf( "Hadd %d carry is wrong.\n", iBox );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void Acec_TreeVerifyPhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes, Vec_Bit_t * vPhase )
|
|
|
|
|
{
|
|
|
|
|
Vec_Int_t * vLevel;
|
|
|
|
|
int i, k, Box;
|
|
|
|
|
Vec_WecForEachLevel( vBoxes, vLevel, i )
|
|
|
|
|
Vec_IntForEachEntry( vLevel, Box, k )
|
|
|
|
|
Acec_TreeVerifyPhaseOne( p, vAdds, Box, vPhase );
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-10 13:19:02 +01:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Creates polarity.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2017-01-11 07:36:54 +01:00
|
|
|
Vec_Int_t * Acec_TreeCarryMap( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes )
|
|
|
|
|
{
|
|
|
|
|
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
|
|
|
|
|
Vec_Int_t * vLevel;
|
|
|
|
|
int i, k, Box;
|
|
|
|
|
Vec_WecForEachLevel( vBoxes, vLevel, i )
|
|
|
|
|
Vec_IntForEachEntry( vLevel, Box, k )
|
|
|
|
|
Vec_IntWriteEntry( vMap, Vec_IntEntry(vAdds, 6*Box+4), Box );
|
|
|
|
|
return vMap;
|
|
|
|
|
}
|
|
|
|
|
void Acec_TreePhases_rec( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vMap, int Node, int fPhase,
|
|
|
|
|
Vec_Bit_t * vPhase, Vec_Bit_t * vInvHadds, Vec_Bit_t * vVisit )
|
|
|
|
|
{
|
|
|
|
|
int k, iBox, iXor, Sign, fXorPhase, fPhaseThis;
|
|
|
|
|
assert( Node != 0 );
|
|
|
|
|
if ( Vec_BitEntry(vVisit, Node) )
|
|
|
|
|
{
|
|
|
|
|
assert( Vec_BitEntry(vPhase, Node) == fPhase );
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Vec_BitWriteEntry( vVisit, Node, 1 );
|
|
|
|
|
if ( fPhase )
|
|
|
|
|
Vec_BitWriteEntry( vPhase, Node, fPhase );
|
|
|
|
|
iBox = Vec_IntEntry( vMap, Node );
|
|
|
|
|
if ( iBox == -1 )
|
|
|
|
|
return;
|
|
|
|
|
assert( Node == Vec_IntEntry( vAdds, 6*iBox+4 ) );
|
|
|
|
|
iXor = Vec_IntEntry( vAdds, 6*iBox+3 );
|
|
|
|
|
Sign = Vec_IntEntry( vAdds, 6*iBox+5 );
|
|
|
|
|
fXorPhase = ((Sign >> 3) & 1);
|
|
|
|
|
if ( Vec_IntEntry(vAdds, 6*iBox+2) == 0 )
|
|
|
|
|
{
|
|
|
|
|
fPhase ^= ((Sign >> 2) & 1);
|
|
|
|
|
// remember complemented HADD
|
|
|
|
|
if ( fPhase )
|
|
|
|
|
Vec_BitWriteEntry( vInvHadds, iBox, 1 );
|
|
|
|
|
}
|
|
|
|
|
for ( k = 0; k < 3; k++ )
|
|
|
|
|
{
|
|
|
|
|
int iObj = Vec_IntEntry( vAdds, 6*iBox+k );
|
|
|
|
|
if ( iObj == 0 )
|
|
|
|
|
continue;
|
|
|
|
|
fPhaseThis = ((Sign >> k) & 1) ^ fPhase;
|
|
|
|
|
fXorPhase ^= fPhaseThis;
|
|
|
|
|
Acec_TreePhases_rec( p, vAdds, vMap, iObj, fPhaseThis, vPhase, vInvHadds, vVisit );
|
|
|
|
|
}
|
|
|
|
|
if ( Vec_BitEntry(vVisit, iXor) )
|
|
|
|
|
assert( Vec_BitEntry(vPhase, iXor) == fXorPhase );
|
|
|
|
|
if ( fXorPhase )
|
|
|
|
|
Vec_BitWriteEntry( vPhase, iXor, fXorPhase );
|
|
|
|
|
}
|
|
|
|
|
void Acec_TreePhases( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Wec_t * vBoxes,
|
|
|
|
|
Vec_Wec_t * vLeaves, Vec_Wec_t * vRoots,
|
|
|
|
|
Vec_Wec_t * vLeafLits, Vec_Wec_t * vRootLits, Vec_Bit_t * vInvHadds )
|
2017-01-10 13:19:02 +01:00
|
|
|
{
|
2017-01-11 07:36:54 +01:00
|
|
|
Vec_Int_t * vMap = Acec_TreeCarryMap( p, vAdds, vBoxes );
|
|
|
|
|
Vec_Bit_t * vPhase = Vec_BitStart( Gia_ManObjNum(p) );
|
|
|
|
|
Vec_Bit_t * vVisit = Vec_BitStart( Gia_ManObjNum(p) );
|
|
|
|
|
Vec_Int_t * vLevel;
|
|
|
|
|
int i, k, iObj;
|
|
|
|
|
Vec_WecForEachLevelReverse( vRoots, vLevel, i )
|
|
|
|
|
{
|
|
|
|
|
Vec_IntForEachEntry( vLevel, iObj, k )
|
|
|
|
|
{
|
|
|
|
|
int fFadd = Abc_LitIsCompl(iObj);
|
|
|
|
|
int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj));
|
|
|
|
|
int Node = Abc_Lit2Var(Abc_Lit2Var(iObj));
|
|
|
|
|
if ( !fCout )
|
|
|
|
|
continue;
|
|
|
|
|
Acec_TreePhases_rec( p, vAdds, vMap, Node, fFadd, vPhase, vInvHadds, vVisit );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Vec_IntFree( vMap );
|
|
|
|
|
Vec_BitFree( vVisit );
|
|
|
|
|
Acec_TreeVerifyPhases( p, vAdds, vBoxes, vPhase );
|
|
|
|
|
// create leaves
|
|
|
|
|
Vec_WecForEachLevel( vLeaves, vLevel, i )
|
|
|
|
|
Vec_IntForEachEntry( vLevel, iObj, k )
|
|
|
|
|
Vec_WecPush( vLeafLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) );
|
|
|
|
|
// add constants
|
|
|
|
|
Vec_WecForEachLevel( vBoxes, vLevel, i )
|
|
|
|
|
Vec_IntForEachEntry( vLevel, iObj, k )
|
|
|
|
|
if ( Vec_BitEntry(vInvHadds, iObj) )
|
|
|
|
|
Vec_WecPush( vLeafLits, i, 1 );
|
|
|
|
|
// create roots
|
|
|
|
|
Vec_WecForEachLevel( vRoots, vLevel, i )
|
|
|
|
|
Vec_IntForEachEntry( vLevel, iObj, k )
|
|
|
|
|
iObj >>= 2, Vec_WecPush( vRootLits, i, Abc_Var2Lit(iObj, Vec_BitEntry(vPhase, iObj)) );
|
|
|
|
|
// cleanup
|
|
|
|
|
Vec_BitFree( vPhase );
|
2017-01-10 13:19:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis [Derives one adder tree.]
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2017-01-11 07:36:54 +01:00
|
|
|
void Acec_PrintAdders( Vec_Wec_t * vBoxes, Vec_Int_t * vAdds )
|
|
|
|
|
{
|
|
|
|
|
Vec_Int_t * vLevel;
|
|
|
|
|
int i, k, iBox;
|
|
|
|
|
Vec_WecForEachLevel( vBoxes, vLevel, i )
|
|
|
|
|
{
|
|
|
|
|
printf( " %4d : {", i );
|
|
|
|
|
Vec_IntForEachEntry( vLevel, iBox, k )
|
2017-01-11 10:08:23 +01:00
|
|
|
printf( " %s%d=(%d,%d)", Vec_IntEntry(vAdds, 6*iBox+2) == 0 ? "*":"", iBox,
|
|
|
|
|
Vec_IntEntry(vAdds, 6*iBox+3), Vec_IntEntry(vAdds, 6*iBox+4) );
|
2017-01-11 07:36:54 +01:00
|
|
|
printf( " }\n" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void Vec_WecPrintLits( Vec_Wec_t * p )
|
|
|
|
|
{
|
|
|
|
|
Vec_Int_t * vVec;
|
|
|
|
|
int i, k, Entry;
|
|
|
|
|
Vec_WecForEachLevel( p, vVec, i )
|
|
|
|
|
{
|
|
|
|
|
printf( " %4d : {", i );
|
|
|
|
|
Vec_IntForEachEntry( vVec, Entry, k )
|
|
|
|
|
printf( " %c%d", Abc_LitIsCompl(Entry) ? '-' : '+', Abc_Lit2Var(Entry) );
|
|
|
|
|
printf( " }\n" );
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-01-11 10:08:23 +01:00
|
|
|
void Acec_PrintRootLits( Vec_Wec_t * vRoots )
|
|
|
|
|
{
|
|
|
|
|
Vec_Int_t * vLevel;
|
|
|
|
|
int i, k, iObj;
|
|
|
|
|
Vec_WecForEachLevel( vRoots, vLevel, i )
|
|
|
|
|
{
|
|
|
|
|
printf( "Rank %d : ", i );
|
|
|
|
|
Vec_IntForEachEntry( vLevel, iObj, k )
|
|
|
|
|
{
|
|
|
|
|
int fFadd = Abc_LitIsCompl(iObj);
|
|
|
|
|
int fCout = Abc_LitIsCompl(Abc_Lit2Var(iObj));
|
|
|
|
|
int Node = Abc_Lit2Var(Abc_Lit2Var(iObj));
|
|
|
|
|
printf( "%d%s%s ", Node, fCout ? "*" : "", (fCout && fFadd) ? "*" : "" );
|
|
|
|
|
}
|
|
|
|
|
printf( "\n" );
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-01-11 07:36:54 +01:00
|
|
|
void Acec_PrintBox( Acec_Box_t * pBox, Vec_Int_t * vAdds )
|
|
|
|
|
{
|
|
|
|
|
printf( "Adders:\n" );
|
|
|
|
|
Acec_PrintAdders( pBox->vAdds, vAdds );
|
|
|
|
|
printf( "Inputs:\n" );
|
|
|
|
|
Vec_WecPrintLits( pBox->vLeafLits );
|
|
|
|
|
printf( "Outputs:\n" );
|
|
|
|
|
Vec_WecPrintLits( pBox->vRootLits );
|
|
|
|
|
//printf( "Raw outputs:\n" );
|
|
|
|
|
//Acec_PrintRootLits( pBox->vRoots );
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-10 13:19:02 +01:00
|
|
|
Acec_Box_t * Acec_CreateBox( Gia_Man_t * p, Vec_Int_t * vAdds, Vec_Int_t * vTree )
|
|
|
|
|
{
|
2017-01-11 07:36:54 +01:00
|
|
|
int MaxRank = Acec_CreateBoxMaxRank(vTree);
|
|
|
|
|
|
2017-01-10 13:19:02 +01:00
|
|
|
Acec_Box_t * pBox = ABC_CALLOC( Acec_Box_t, 1 );
|
|
|
|
|
pBox->pGia = p;
|
|
|
|
|
|
2017-01-11 07:36:54 +01:00
|
|
|
pBox->vAdds = Vec_WecStart( MaxRank + 1 );
|
|
|
|
|
pBox->vLeafs = Vec_WecStart( MaxRank + 1 );
|
|
|
|
|
pBox->vRoots = Vec_WecStart( MaxRank + 2 );
|
2017-01-10 13:19:02 +01:00
|
|
|
|
2017-01-11 07:36:54 +01:00
|
|
|
Acec_TreeInsOuts( p, vAdds, vTree, pBox->vAdds, pBox->vLeafs, pBox->vRoots );
|
2017-01-10 13:19:02 +01:00
|
|
|
|
|
|
|
|
pBox->vLeafLits = Vec_WecStart( Vec_WecSize(pBox->vLeafs) );
|
|
|
|
|
pBox->vRootLits = Vec_WecStart( Vec_WecSize(pBox->vRoots) );
|
2017-01-11 07:36:54 +01:00
|
|
|
pBox->vInvHadds = Vec_BitStart( Vec_IntSize(vAdds)/6 );
|
2017-01-10 13:19:02 +01:00
|
|
|
|
2017-01-11 07:36:54 +01:00
|
|
|
Acec_TreePhases( p, vAdds, pBox->vAdds, pBox->vLeafs, pBox->vRoots, pBox->vLeafLits, pBox->vRootLits, pBox->vInvHadds );
|
2017-01-10 13:19:02 +01:00
|
|
|
|
|
|
|
|
return pBox;
|
|
|
|
|
}
|
|
|
|
|
void Acec_CreateBoxTest( Gia_Man_t * p )
|
|
|
|
|
{
|
|
|
|
|
Acec_Box_t * pBox;
|
|
|
|
|
Vec_Wec_t * vTrees;
|
2017-01-11 07:36:54 +01:00
|
|
|
Vec_Int_t * vTree;
|
2017-01-10 13:19:02 +01:00
|
|
|
|
|
|
|
|
abctime clk = Abc_Clock();
|
|
|
|
|
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, 1 );
|
2017-01-11 07:36:54 +01:00
|
|
|
int i, nFadds = Ree_ManCountFadds( vAdds );
|
2017-01-10 13:19:02 +01:00
|
|
|
printf( "Detected %d adders (%d FAs and %d HAs). ", Vec_IntSize(vAdds)/6, nFadds, Vec_IntSize(vAdds)/6-nFadds );
|
|
|
|
|
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
|
|
|
|
|
|
|
|
|
clk = Abc_Clock();
|
|
|
|
|
vTrees = Acec_TreeFindTrees( p, vAdds );
|
|
|
|
|
printf( "Collected %d trees with %d adders in them. ", Vec_WecSize(vTrees), Vec_WecSizeSize(vTrees)/2 );
|
|
|
|
|
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
2017-01-11 07:36:54 +01:00
|
|
|
//Vec_WecPrint( vTrees, 0 );
|
2017-01-10 13:19:02 +01:00
|
|
|
|
2017-01-11 07:36:54 +01:00
|
|
|
Vec_WecForEachLevel( vTrees, vTree, i )
|
|
|
|
|
{
|
|
|
|
|
pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, i) );
|
|
|
|
|
printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n",
|
|
|
|
|
i, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds),
|
|
|
|
|
Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) );
|
2017-01-11 10:08:23 +01:00
|
|
|
Acec_PrintBox( pBox, vAdds );
|
|
|
|
|
Acec_BoxFreeP( &pBox );
|
2017-01-11 07:36:54 +01:00
|
|
|
}
|
2017-01-10 13:19:02 +01:00
|
|
|
|
|
|
|
|
Vec_WecFree( vTrees );
|
|
|
|
|
Vec_IntFree( vAdds );
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-10 10:58:24 +01:00
|
|
|
/**Function*************************************************************
|
|
|
|
|
|
|
|
|
|
Synopsis []
|
|
|
|
|
|
|
|
|
|
Description []
|
|
|
|
|
|
|
|
|
|
SideEffects []
|
|
|
|
|
|
|
|
|
|
SeeAlso []
|
|
|
|
|
|
|
|
|
|
***********************************************************************/
|
2017-01-11 10:08:23 +01:00
|
|
|
Acec_Box_t * Acec_DeriveBox( Gia_Man_t * p, int fVerbose )
|
2017-01-10 10:58:24 +01:00
|
|
|
{
|
2017-01-11 10:08:23 +01:00
|
|
|
Acec_Box_t * pBox = NULL;
|
|
|
|
|
Vec_Int_t * vAdds = Ree_ManComputeCuts( p, NULL, fVerbose );
|
|
|
|
|
Vec_Wec_t * vTrees = Acec_TreeFindTrees( p, vAdds );
|
|
|
|
|
if ( vTrees && Vec_WecSize(vTrees) > 0 )
|
|
|
|
|
pBox = Acec_CreateBox( p, vAdds, Vec_WecEntry(vTrees, 0) );
|
|
|
|
|
if ( pBox )//&& fVerbose )
|
|
|
|
|
printf( "Processing tree %d: Ranks = %d. Adders = %d. Leaves = %d. Roots = %d.\n",
|
|
|
|
|
0, Vec_WecSize(pBox->vAdds), Vec_WecSizeSize(pBox->vAdds),
|
|
|
|
|
Vec_WecSizeSize(pBox->vLeafLits), Vec_WecSizeSize(pBox->vRootLits) );
|
|
|
|
|
if ( pBox && fVerbose )
|
|
|
|
|
Acec_PrintBox( pBox, vAdds );
|
|
|
|
|
Vec_WecFreeP( &vTrees );
|
|
|
|
|
Vec_IntFree( vAdds );
|
|
|
|
|
return pBox;
|
2017-01-10 10:58:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
/// END OF FILE ///
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
|
|