blob: 6702e13be48b61eb329bacaedd4548974775595b [file] [log] [blame]
/**CFile****************************************************************
FileName [acecStruct.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [CEC for arithmetic circuits.]
Synopsis [Core procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: acecStruct.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "acecInt.h"
#include "misc/vec/vecWec.h"
#include "misc/extra/extra.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Acec_StructDetectXorRoots( Gia_Man_t * p )
{
Vec_Int_t * vXors = Vec_IntAlloc( 100 );
Vec_Bit_t * vXorIns = Vec_BitStart( Gia_ManObjNum(p) );
Gia_Obj_t * pFan0, * pFan1, * pObj;
int i, k = 0, Entry;
Gia_ManForEachAnd( p, pObj, i )
{
if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
continue;
Vec_IntPush( vXors, i );
Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan0)), 1 );
Vec_BitWriteEntry( vXorIns, Gia_ObjId(p, Gia_Regular(pFan1)), 1 );
}
// collect XORs that not inputs of other XORs
Vec_IntForEachEntry( vXors, Entry, i )
if ( !Vec_BitEntry(vXorIns, Entry) )
Vec_IntWriteEntry( vXors, k++, Entry );
Vec_IntShrink( vXors, k );
Vec_BitFree( vXorIns );
return vXors;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Acec_StructAssignRanks( Gia_Man_t * p, Vec_Int_t * vXorRoots )
{
Vec_Int_t * vDoubles = Vec_IntAlloc( 100 );
Gia_Obj_t * pFan0, * pFan1, * pObj;
int i, k, Fanins[2], Entry, Rank;
// map roots into their ranks
Vec_Int_t * vRanks = Vec_IntStartFull( Gia_ManObjNum(p) );
Vec_IntForEachEntry( vXorRoots, Entry, i )
Vec_IntWriteEntry( vRanks, Entry, i );
// map nodes into their ranks
Gia_ManForEachAndReverse( p, pObj, i )
{
if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
continue;
Rank = Vec_IntEntry( vRanks, i );
// skip XORs that are not part of any tree
if ( Rank == -1 )
continue;
// iterate through XOR inputs
Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0));
Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1));
for ( k = 0; k < 2; k++ )
{
Entry = Vec_IntEntry( vRanks, Fanins[k] );
if ( Entry == Rank ) // the same tree -- allow fanout in this tree
continue;
if ( Entry == -1 )
Vec_IntWriteEntry( vRanks, Fanins[k], Rank );
else
Vec_IntPush( vDoubles, Fanins[k] );
if ( Entry != -1 && Gia_ObjIsAnd(Gia_ManObj(p, Fanins[k])))
printf( "Xor node %d belongs to Tree %d and Tree %d.\n", Fanins[k], Entry, Rank );
}
}
// remove duplicated entries
Vec_IntForEachEntry( vDoubles, Entry, i )
Vec_IntWriteEntry( vRanks, Entry, -1 );
Vec_IntFree( vDoubles );
return vRanks;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Wec_t * Acec_FindTreeLeaves( Gia_Man_t * p, Vec_Int_t * vXorRoots, Vec_Int_t * vRanks )
{
Vec_Bit_t * vMapXors = Vec_BitStart( Gia_ManObjNum(p) );
Vec_Wec_t * vTreeLeaves = Vec_WecStart( Vec_IntSize(vXorRoots) );
Gia_Obj_t * pFan0, * pFan1, * pObj;
int i, k, Fanins[2], Rank;
Gia_ManForEachAnd( p, pObj, i )
{
if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
continue;
Vec_BitWriteEntry( vMapXors, i, 1 );
Rank = Vec_IntEntry( vRanks, i );
// skip XORs that are not part of any tree
if ( Rank == -1 )
continue;
// iterate through XOR inputs
Fanins[0] = Gia_ObjId(p, Gia_Regular(pFan0));
Fanins[1] = Gia_ObjId(p, Gia_Regular(pFan1));
for ( k = 0; k < 2; k++ )
{
if ( Vec_BitEntry(vMapXors, Fanins[k]) )
{
assert( Rank == Vec_IntEntry(vRanks, Fanins[k]) );
continue;
}
Vec_WecPush( vTreeLeaves, Rank, Fanins[k] );
}
}
Vec_BitFree( vMapXors );
return vTreeLeaves;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Acec_FindShadows( Gia_Man_t * p, Vec_Int_t * vRanks )
{
Vec_Int_t * vShadows = Vec_IntDup( vRanks );
Gia_Obj_t * pObj; int i, Shad0, Shad1;
Gia_ManForEachCi( p, pObj, i )
Vec_IntWriteEntry( vShadows, Gia_ObjId(p, pObj), -1 );
Gia_ManForEachAnd( p, pObj, i )
{
if ( Vec_IntEntry(vShadows, i) >= 0 )
continue;
Shad0 = Vec_IntEntry(vShadows, Gia_ObjFaninId0(pObj, i));
Shad1 = Vec_IntEntry(vShadows, Gia_ObjFaninId1(pObj, i));
if ( Shad0 == Shad1 && Shad0 != -1 )
Vec_IntWriteEntry(vShadows, i, Shad0);
}
return vShadows;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Acec_CollectSupp_rec( Gia_Man_t * p, int iNode, int Rank, Vec_Int_t * vRanks )
{
Gia_Obj_t * pObj;
int nSize;
if ( Gia_ObjIsTravIdCurrentId(p, iNode) )
return 0;
Gia_ObjSetTravIdCurrentId(p, iNode);
pObj = Gia_ManObj(p, iNode);
assert( Gia_ObjIsAnd(pObj) );
if ( Vec_IntEntry(vRanks, iNode) == Rank )
return 1;
nSize = Acec_CollectSupp_rec( p, Gia_ObjFaninId0(pObj, iNode), Rank, vRanks );
nSize += Acec_CollectSupp_rec( p, Gia_ObjFaninId1(pObj, iNode), Rank, vRanks );
return nSize;
}
Vec_Wec_t * Acec_FindNexts( Gia_Man_t * p, Vec_Int_t * vRanks, Vec_Int_t * vShadows, Vec_Wec_t * vTreeLeaves )
{
Vec_Wec_t * vNexts = Vec_WecStart( Vec_WecSize(vTreeLeaves) );
Vec_Int_t * vTree;
int i, k, Node, Fanins[2], Shad0, Shad1, Rank, nSupp;
Vec_WecForEachLevel( vTreeLeaves, vTree, i )
Vec_IntForEachEntry( vTree, Node, k )
{
Gia_Obj_t * pObj = Gia_ManObj(p, Node);
if ( !Gia_ObjIsAnd(pObj) )
continue;
Fanins[0] = Gia_ObjFaninId0(pObj, Node);
Fanins[1] = Gia_ObjFaninId1(pObj, Node);
Shad0 = Vec_IntEntry(vShadows, Fanins[0]);
Shad1 = Vec_IntEntry(vShadows, Fanins[1]);
if ( Shad0 != Shad1 || Shad0 == -1 )
continue;
// check support size of Node in terms of the shadow of its fanins
Rank = Vec_IntEntry( vRanks, Node );
assert( Rank != Shad0 );
Gia_ManIncrementTravId( p );
nSupp = Acec_CollectSupp_rec( p, Node, Shad0, vRanks );
assert( nSupp > 1 );
if ( nSupp > 3 )
continue;
Vec_IntPushUniqueOrder( Vec_WecEntry(vNexts, Shad0), Rank );
}
return vNexts;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Acec_StructTest( Gia_Man_t * p )
{
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END