blob: edcbe7edc09cc90637e56108975fd0945beb77b8 [file] [log] [blame]
/**CFile****************************************************************
FileName [absRpm.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Abstraction package.]
Synopsis [Structural reparameterization.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: absRpm.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "abs.h"
#include "misc/vec/vecWec.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static inline int Gia_ObjDom( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vDoms, Gia_ObjId(p, pObj)); }
static inline void Gia_ObjSetDom( Gia_Man_t * p, Gia_Obj_t * pObj, int d ) { Vec_IntWriteEntry(p->vDoms, Gia_ObjId(p, pObj), d); }
static int Abs_ManSupport2( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp );
static int Abs_GiaObjDeref_rec( Gia_Man_t * p, Gia_Obj_t * pNode );
static int Abs_GiaObjRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes one-node dominators.]
Description [For each node, computes the closest one-node dominator,
which can be the node itself if the node has no other dominators.]
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManAddDom( Gia_Man_t * p, Gia_Obj_t * pObj, int iDom0 )
{
int iDom1, iDomNext;
if ( Gia_ObjDom(p, pObj) == -1 )
{
Gia_ObjSetDom( p, pObj, iDom0 );
return;
}
iDom1 = Gia_ObjDom( p, pObj );
while ( 1 )
{
if ( iDom0 > iDom1 )
{
iDomNext = Gia_ObjDom( p, Gia_ManObj(p, iDom1) );
if ( iDomNext == iDom1 )
break;
iDom1 = iDomNext;
continue;
}
if ( iDom1 > iDom0 )
{
iDomNext = Gia_ObjDom( p, Gia_ManObj(p, iDom0) );
if ( iDomNext == iDom0 )
break;
iDom0 = iDomNext;
continue;
}
assert( iDom0 == iDom1 );
Gia_ObjSetDom( p, pObj, iDom0 );
return;
}
Gia_ObjSetDom( p, pObj, Gia_ObjId(p, pObj) );
}
void Gia_ManComputeDoms( Gia_Man_t * p )
{
Gia_Obj_t * pObj;
int i;
if ( p->vDoms == NULL )
p->vDoms = Vec_IntAlloc( 0 );
Vec_IntFill( p->vDoms, Gia_ManObjNum(p), -1 );
Gia_ManForEachObjReverse( p, pObj, i )
{
if ( i == 0 || Gia_ObjIsCi(pObj) )
continue;
if ( pObj->fMark1 || (p->pRefs && Gia_ObjIsAnd(pObj) && Gia_ObjRefNum(p, pObj) == 0) )
continue;
if ( Gia_ObjIsCo(pObj) )
{
Gia_ObjSetDom( p, pObj, i );
Gia_ManAddDom( p, Gia_ObjFanin0(pObj), i );
continue;
}
assert( Gia_ObjIsAnd(pObj) );
Gia_ManAddDom( p, Gia_ObjFanin0(pObj), i );
Gia_ManAddDom( p, Gia_ObjFanin1(pObj), i );
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Wec_t * Gia_ManCreateSupps( Gia_Man_t * p, int fVerbose )
{
abctime clk = Abc_Clock();
Gia_Obj_t * pObj; int i, Id;
Vec_Wec_t * vSupps = Vec_WecStart( Gia_ManObjNum(p) );
Gia_ManForEachCiId( p, Id, i )
Vec_IntPush( Vec_WecEntry(vSupps, Id), i );
Gia_ManForEachAnd( p, pObj, Id )
Vec_IntTwoMerge2( Vec_WecEntry(vSupps, Gia_ObjFaninId0(pObj, Id)),
Vec_WecEntry(vSupps, Gia_ObjFaninId1(pObj, Id)),
Vec_WecEntry(vSupps, Id) );
// Gia_ManForEachCo( p, pObj, i )
// Vec_IntAppend( Vec_WecEntry(vSupps, Gia_ObjId(p, pObj)), Vec_WecEntry(vSupps, Gia_ObjFaninId0p(p, pObj)) );
if ( fVerbose )
Abc_PrintTime( 1, "Support computation", Abc_Clock() - clk );
return vSupps;
}
void Gia_ManDomTest( Gia_Man_t * p )
{
Vec_Int_t * vDoms = Vec_IntAlloc( 100 );
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
Vec_Wec_t * vSupps = Gia_ManCreateSupps( p, 1 );
Vec_Wec_t * vDomeds = Vec_WecStart( Gia_ManObjNum(p) );
Gia_Obj_t * pObj, * pDom; int i, Id, nMffcSize;
Gia_ManCreateRefs( p );
Gia_ManComputeDoms( p );
Gia_ManForEachCi( p, pObj, i )
{
if ( Gia_ObjDom(p, pObj) == -1 )
continue;
for ( pDom = Gia_ManObj(p, Gia_ObjDom(p, pObj)); Gia_ObjIsAnd(pDom); pDom = Gia_ManObj(p, Gia_ObjDom(p, pDom)) )
Vec_IntPush( Vec_WecEntry(vDomeds, Gia_ObjId(p, pDom)), i );
}
Gia_ManForEachAnd( p, pObj, i )
if ( Vec_IntEqual(Vec_WecEntry(vSupps, i), Vec_WecEntry(vDomeds, i)) )
Vec_IntPush( vDoms, i );
Vec_WecFree( vSupps );
Vec_WecFree( vDomeds );
// check MFFC sizes
Vec_IntForEachEntry( vDoms, Id, i )
Gia_ObjRefInc( p, Gia_ManObj(p, Id) );
Vec_IntForEachEntry( vDoms, Id, i )
{
nMffcSize = Gia_NodeMffcSizeSupp( p, Gia_ManObj(p, Id), vSupp );
printf( "%d(%d:%d) ", Id, Vec_IntSize(vSupp), nMffcSize );
}
printf( "\n" );
Vec_IntForEachEntry( vDoms, Id, i )
Gia_ObjRefDec( p, Gia_ManObj(p, Id) );
// Vec_IntPrint( vDoms );
Vec_IntFree( vDoms );
Vec_IntFree( vSupp );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManTestDoms2( Gia_Man_t * p )
{
Vec_Int_t * vNodes;
Gia_Obj_t * pObj, * pDom;
abctime clk = Abc_Clock();
int i;
assert( p->vDoms == NULL );
Gia_ManComputeDoms( p );
/*
Gia_ManForEachPi( p, pObj, i )
if ( Gia_ObjId(p, pObj) != Gia_ObjDom(p, pObj) )
printf( "PI =%6d Id =%8d. Dom =%8d.\n", i, Gia_ObjId(p, pObj), Gia_ObjDom(p, pObj) );
*/
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
// for each dominated PI, when if the PIs is in a leaf of the MFFC of the dominator
Gia_ManCleanMark1( p );
Gia_ManForEachPi( p, pObj, i )
pObj->fMark1 = 1;
vNodes = Vec_IntAlloc( 100 );
Gia_ManCreateRefs( p );
Gia_ManForEachPi( p, pObj, i )
{
if ( Gia_ObjId(p, pObj) == Gia_ObjDom(p, pObj) )
continue;
pDom = Gia_ManObj(p, Gia_ObjDom(p, pObj));
if ( Gia_ObjIsCo(pDom) )
{
assert( Gia_ObjFanin0(pDom) == pObj );
continue;
}
assert( Gia_ObjIsAnd(pDom) );
Abs_GiaObjDeref_rec( p, pDom );
Abs_ManSupport2( p, pDom, vNodes );
Abs_GiaObjRef_rec( p, pDom );
if ( Vec_IntFind(vNodes, Gia_ObjId(p, pObj)) == -1 )
printf( "FAILURE.\n" );
// else
// printf( "Success.\n" );
}
Vec_IntFree( vNodes );
Gia_ManCleanMark1( p );
}
/**Function*************************************************************
Synopsis [Collect PI doms.]
Description [Assumes that some PIs and ANDs are marked with fMark1.]
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Gia_ManCollectDoms( Gia_Man_t * p )
{
Vec_Int_t * vNodes;
Gia_Obj_t * pObj;
int Lev, LevMax = ABC_INFINITY;
int i, iDom, iDomNext;
vNodes = Vec_IntAlloc( 100 );
Gia_ManForEachObj( p, pObj, i )
{
if ( !pObj->fMark1 )
continue;
if ( p->pRefs && Gia_ObjRefNum(p, pObj) == 0 )
continue;
iDom = Gia_ObjDom(p, pObj);
if ( iDom == -1 )
continue;
if ( iDom == i )
continue;
for ( Lev = 0; Lev < LevMax && Gia_ObjIsAnd( Gia_ManObj(p, iDom) ); Lev++ )
{
Vec_IntPush( vNodes, iDom );
iDomNext = Gia_ObjDom( p, Gia_ManObj(p, iDom) );
if ( iDomNext == iDom )
break;
iDom = iDomNext;
}
}
Vec_IntUniqify( vNodes );
return vNodes;
}
Vec_Int_t * Gia_ManComputePiDoms( Gia_Man_t * p )
{
Vec_Int_t * vNodes;
Gia_ManComputeDoms( p );
vNodes = Gia_ManCollectDoms( p );
// Vec_IntPrint( vNodes );
return vNodes;
}
void Gia_ManTestDoms( Gia_Man_t * p )
{
Vec_Int_t * vNodes;
Gia_Obj_t * pObj;
int i;
// mark PIs
// Gia_ManCreateRefs( p );
Gia_ManCleanMark1( p );
Gia_ManForEachPi( p, pObj, i )
pObj->fMark1 = 1;
// compute dominators
assert( p->vDoms == NULL );
vNodes = Gia_ManComputePiDoms( p );
// printf( "Nodes = %d. Doms = %d.\n", Gia_ManAndNum(p), Vec_IntSize(vNodes) );
Vec_IntFree( vNodes );
// unmark PIs
Gia_ManCleanMark1( p );
}
/**Function*************************************************************
Synopsis [Counts flops without fanout.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManCountFanoutlessFlops( Gia_Man_t * p )
{
Gia_Obj_t * pObj;
int i;
int Counter = 0;
Gia_ManCreateRefs( p );
Gia_ManForEachRo( p, pObj, i )
if ( Gia_ObjRefNum(p, pObj) == 0 )
Counter++;
printf( "Fanoutless flops = %d.\n", Counter );
ABC_FREE( p->pRefs );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManCountPisNodes_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vPis, Vec_Int_t * vAnds )
{
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return;
Gia_ObjSetTravIdCurrent(p, pObj);
if ( pObj->fMark1 )
{
Vec_IntPush( vPis, Gia_ObjId(p, pObj) );
return;
}
assert( Gia_ObjIsAnd(pObj) );
Gia_ManCountPisNodes_rec( p, Gia_ObjFanin0(pObj), vPis, vAnds );
Gia_ManCountPisNodes_rec( p, Gia_ObjFanin1(pObj), vPis, vAnds );
Vec_IntPush( vAnds, Gia_ObjId(p, pObj) );
}
void Gia_ManCountPisNodes( Gia_Man_t * p, Vec_Int_t * vPis, Vec_Int_t * vAnds )
{
Gia_Obj_t * pObj;
int i;
// mark const0 and flop output
Gia_ManIncrementTravId( p );
Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
Gia_ManForEachRo( p, pObj, i )
Gia_ObjSetTravIdCurrent( p, pObj );
// count PIs and internal nodes reachable from COs
Vec_IntClear( vPis );
Vec_IntClear( vAnds );
Gia_ManForEachCo( p, pObj, i )
Gia_ManCountPisNodes_rec( p, Gia_ObjFanin0(pObj), vPis, vAnds );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abs_GiaObjDeref_rec( Gia_Man_t * p, Gia_Obj_t * pNode )
{
Gia_Obj_t * pFanin;
int Counter = 0;
if ( pNode->fMark1 || Gia_ObjIsRo(p, pNode) )
return 0;
assert( Gia_ObjIsAnd(pNode) );
pFanin = Gia_ObjFanin0(pNode);
assert( Gia_ObjRefNum(p, pFanin) > 0 );
if ( Gia_ObjRefDec(p, pFanin) == 0 )
Counter += Abs_GiaObjDeref_rec( p, pFanin );
pFanin = Gia_ObjFanin1(pNode);
assert( Gia_ObjRefNum(p, pFanin) > 0 );
if ( Gia_ObjRefDec(p, pFanin) == 0 )
Counter += Abs_GiaObjDeref_rec( p, pFanin );
return Counter + 1;
}
int Abs_GiaObjRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode )
{
Gia_Obj_t * pFanin;
int Counter = 0;
if ( pNode->fMark1 || Gia_ObjIsRo(p, pNode) )
return 0;
assert( Gia_ObjIsAnd(pNode) );
pFanin = Gia_ObjFanin0(pNode);
if ( Gia_ObjRefInc(p, pFanin) == 0 )
Counter += Abs_GiaObjRef_rec( p, pFanin );
pFanin = Gia_ObjFanin1(pNode);
if ( Gia_ObjRefInc(p, pFanin) == 0 )
Counter += Abs_GiaObjRef_rec( p, pFanin );
return Counter + 1;
}
/**Function*************************************************************
Synopsis [Returns the number of nodes with zero refs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abs_GiaSortNodes( Gia_Man_t * p, Vec_Int_t * vSupp )
{
Gia_Obj_t * pObj;
int nSize = Vec_IntSize(vSupp);
int i, RetValue;
Gia_ManForEachObjVec( vSupp, p, pObj, i )
if ( i < nSize && Gia_ObjRefNum(p, pObj) == 0 && !Gia_ObjIsRo(p, pObj) ) // add removable leaves
{
assert( pObj->fMark1 );
Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
}
RetValue = Vec_IntSize(vSupp) - nSize;
Gia_ManForEachObjVec( vSupp, p, pObj, i )
if ( i < nSize && !(Gia_ObjRefNum(p, pObj) == 0 && !Gia_ObjIsRo(p, pObj)) ) // add non-removable leaves
Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
assert( Vec_IntSize(vSupp) == 2 * nSize );
memmove( Vec_IntArray(vSupp), Vec_IntArray(vSupp) + nSize, sizeof(int) * nSize );
Vec_IntShrink( vSupp, nSize );
return RetValue;
}
/**Function*************************************************************
Synopsis [Computes support in terms of PIs and flops.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abs_ManSupport1_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp )
{
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return;
Gia_ObjSetTravIdCurrent(p, pObj);
if ( pObj->fMark1 || Gia_ObjIsRo(p, pObj) )
{
Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
return;
}
assert( Gia_ObjIsAnd(pObj) );
Abs_ManSupport1_rec( p, Gia_ObjFanin0(pObj), vSupp );
Abs_ManSupport1_rec( p, Gia_ObjFanin1(pObj), vSupp );
}
int Abs_ManSupport1( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp )
{
assert( Gia_ObjIsAnd(pObj) );
Vec_IntClear( vSupp );
Gia_ManIncrementTravId( p );
Abs_ManSupport1_rec( p, pObj, vSupp );
return Vec_IntSize(vSupp);
}
/**Function*************************************************************
Synopsis [Computes support of the MFFC.]
Description [Should be called when pObj's cone is dereferenced.]
SideEffects []
SeeAlso []
***********************************************************************/
void Abs_ManSupport2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp )
{
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return;
Gia_ObjSetTravIdCurrent(p, pObj);
if ( pObj->fMark1 || Gia_ObjIsRo(p, pObj) || Gia_ObjRefNum(p, pObj) > 0 )
{
Vec_IntPush( vSupp, Gia_ObjId(p, pObj) );
return;
}
assert( Gia_ObjIsAnd(pObj) );
Abs_ManSupport2_rec( p, Gia_ObjFanin0(pObj), vSupp );
Abs_ManSupport2_rec( p, Gia_ObjFanin1(pObj), vSupp );
}
int Abs_ManSupport2( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp )
{
assert( Gia_ObjIsAnd(pObj) );
Vec_IntClear( vSupp );
Gia_ManIncrementTravId( p );
Abs_ManSupport2_rec( p, Gia_ObjFanin0(pObj), vSupp );
Abs_ManSupport2_rec( p, Gia_ObjFanin1(pObj), vSupp );
Gia_ObjSetTravIdCurrent(p, pObj);
return Vec_IntSize(vSupp);
}
/**Function*************************************************************
Synopsis [Computes support of the extended MFFC.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abs_ManSupport3( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vSupp )
{
Gia_Obj_t * pTemp, * pFan0, * pFan1;
int i, nSize0;
// collect MFFC
Abs_ManSupport2( p, pObj, vSupp );
// move dominated to the front
nSize0 = Abs_GiaSortNodes( p, vSupp );
assert( nSize0 > 0 );
// consider remaining nodes
while ( 1 )
{
int fChanges = 0;
Gia_ManForEachObjVec( vSupp, p, pTemp, i )
{
if ( i < nSize0 )
continue;
if ( !Gia_ObjIsAnd(pTemp) )
continue;
assert( !pTemp->fMark1 );
assert( Gia_ObjRefNum(p, pTemp) > 0 );
pFan0 = Gia_ObjFanin0(pTemp);
pFan1 = Gia_ObjFanin1(pTemp);
if ( Gia_ObjIsTravIdCurrent(p, pFan0) && Gia_ObjIsTravIdCurrent(p, pFan1) )
{
Vec_IntRemove( vSupp, Gia_ObjId(p, pTemp) );
fChanges = 1;
break;
}
if ( Gia_ObjIsTravIdCurrent(p, pFan0) )
{
Vec_IntRemove( vSupp, Gia_ObjId(p, pTemp) );
Vec_IntPush( vSupp, Gia_ObjId(p, pFan1) );
assert( !Gia_ObjIsTravIdCurrent(p, pFan1) );
Gia_ObjSetTravIdCurrent(p, pFan1);
fChanges = 1;
break;
}
if ( Gia_ObjIsTravIdCurrent(p, pFan1) )
{
Vec_IntRemove( vSupp, Gia_ObjId(p, pTemp) );
Vec_IntPush( vSupp, Gia_ObjId(p, pFan0) );
assert( !Gia_ObjIsTravIdCurrent(p, pFan0) );
Gia_ObjSetTravIdCurrent(p, pFan0);
fChanges = 1;
break;
}
}
if ( !fChanges )
break;
}
return Vec_IntSize(vSupp);
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abs_GiaCofPrint( word * pTruth, int nSize, int nSize0, int Res )
{
int i, Bit;
int nBits = (1 << nSize);
int nStep = (1 << nSize0);
int Mark[2] = {1,1};
for ( i = 0; i < nBits; i++ )
{
if ( i % nStep == 0 )
{
printf( " " );
assert( Res || (Mark[0] && Mark[1]) );
Mark[0] = Mark[1] = 0;
}
Bit = Abc_InfoHasBit((unsigned *)pTruth, i);
Mark[Bit] = 1;
printf( "%d", Bit );
}
printf( "\n" );
assert( Res || (Mark[0] && Mark[1]) );
return 1;
}
/**Function*************************************************************
Synopsis [Returns 1 if truth table has no const cofactors.]
Description [The cofactoring variables are the (nSize-nSize0)
most significant vars. Each cofactor depends on nSize0 vars.]
SideEffects []
SeeAlso []
***********************************************************************/
int Abs_GiaCheckTruth( word * pTruth, int nSize, int nSize0 )
{
unsigned char * pStr = (unsigned char *)pTruth;
int nStr = (nSize >= 3 ? (1 << (nSize - 3)) : 1);
int i, k, nSteps;
assert( nSize0 > 0 && nSize0 <= nSize );
if ( nSize0 == 1 )
{
for ( i = 0; i < nStr; i++ )
if ( (((unsigned)pStr[i] ^ ((unsigned)pStr[i] >> 1)) & 0x55) != 0x55 )
return 0;
return 1;
}
if ( nSize0 == 2 )
{
for ( i = 0; i < nStr; i++ )
if ( ((unsigned)pStr[i] & 0xF) == 0x0 || (((unsigned)pStr[i] >> 4) & 0xF) == 0x0 ||
((unsigned)pStr[i] & 0xF) == 0xF || (((unsigned)pStr[i] >> 4) & 0xF) == 0xF )
return 0;
return 1;
}
assert( nSize0 >= 3 );
nSteps = (1 << (nSize0 - 3));
for ( i = 0; i < nStr; i += nSteps )
{
for ( k = 0; k < nSteps; k++ )
if ( ((unsigned)pStr[i+k] & 0xFF) != 0x00 )
break;
if ( k == nSteps )
break;
for ( k = 0; k < nSteps; k++ )
if ( ((unsigned)pStr[i+k] & 0xFF) != 0xFF )
break;
if ( k == nSteps )
break;
}
assert( i <= nStr );
return (int)( i == nStr );
}
/**Function*************************************************************
Synopsis [Returns 1 if truth table has const cofactors.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abs_RpmPerformMark( Gia_Man_t * p, int nCutMax, int fVerbose, int fVeryVerbose )
{
Vec_Int_t * vPis, * vAnds, * vDoms;
Vec_Int_t * vSupp, * vSupp1, * vSupp2;
Gia_Obj_t * pObj;
word * pTruth;
int Iter, i, nSize0, nNodes;
int fHasConst, fChanges = 1;
Gia_ManCreateRefs( p );
Gia_ManCleanMark1( p );
Gia_ManForEachPi( p, pObj, i )
pObj->fMark1 = 1;
vPis = Vec_IntAlloc( 100 );
vAnds = Vec_IntAlloc( 100 );
vSupp1 = Vec_IntAlloc( 100 );
vSupp2 = Vec_IntAlloc( 100 );
for ( Iter = 0; fChanges; Iter++ )
{
fChanges = 0;
vDoms = Gia_ManComputePiDoms( p );
// count the number of PIs and internal nodes
if ( fVerbose || fVeryVerbose )
{
Gia_ManCountPisNodes( p, vPis, vAnds );
printf( "Iter %3d : ", Iter );
printf( "PI = %5d (%6.2f %%) ", Vec_IntSize(vPis), 100.0 * Vec_IntSize(vPis) / Gia_ManPiNum(p) );
printf( "And = %6d (%6.2f %%) ", Vec_IntSize(vAnds), 100.0 * Vec_IntSize(vAnds) / Gia_ManAndNum(p) );
printf( "Dom = %5d (%6.2f %%) ", Vec_IntSize(vDoms), 100.0 * Vec_IntSize(vDoms) / Gia_ManAndNum(p) );
printf( "\n" );
}
// pObj = Gia_ObjFanin0( Gia_ManPo(p, 1) );
Gia_ManForEachObjVec( vDoms, p, pObj, i )
{
assert( !pObj->fMark1 );
assert( Gia_ObjRefNum( p, pObj ) > 0 );
// dereference root node
nNodes = Abs_GiaObjDeref_rec( p, pObj );
/*
// compute support of full cone
if ( Abs_ManSupport1(p, pObj, vSupp1) > nCutMax )
// if ( 1 )
{
// check support of MFFC
if ( Abs_ManSupport2(p, pObj, vSupp2) > nCutMax )
// if ( 1 )
{
Abs_GiaObjRef_rec( p, pObj );
continue;
}
vSupp = vSupp2;
// printf( "-" );
}
else
{
vSupp = vSupp1;
// printf( "+" );
}
*/
if ( Abs_ManSupport2(p, pObj, vSupp2) > nCutMax )
{
Abs_GiaObjRef_rec( p, pObj );
continue;
}
vSupp = vSupp2;
// order nodes by their ref counts
nSize0 = Abs_GiaSortNodes( p, vSupp );
assert( nSize0 > 0 && nSize0 <= nCutMax );
// check if truth table has const cofs
pTruth = Gia_ObjComputeTruthTableCut( p, pObj, vSupp );
if ( pTruth == NULL )
{
Abs_GiaObjRef_rec( p, pObj );
continue;
}
fHasConst = !Abs_GiaCheckTruth( pTruth, Vec_IntSize(vSupp), nSize0 );
if ( fVeryVerbose )
{
printf( "Nodes =%3d ", nNodes );
printf( "Size =%3d ", Vec_IntSize(vSupp) );
printf( "Size0 =%3d ", nSize0 );
printf( "%3s", fHasConst ? "yes" : "no" );
Abs_GiaCofPrint( pTruth, Vec_IntSize(vSupp), nSize0, fHasConst );
}
if ( fHasConst )
{
Abs_GiaObjRef_rec( p, pObj );
continue;
}
// pObj can be reparamed
pObj->fMark1 = 1;
fChanges = 1;
}
Vec_IntFree( vDoms );
}
// count the number of PIs and internal nodes
if ( fVeryVerbose )
{
Gia_ManCountPisNodes( p, vPis, vAnds );
printf( "Iter %3d : ", Iter );
printf( "PI = %5d (%6.2f %%) ", Vec_IntSize(vPis), 100.0 * Vec_IntSize(vPis) / Gia_ManPiNum(p) );
printf( "And = %6d (%6.2f %%) ", Vec_IntSize(vAnds), 100.0 * Vec_IntSize(vAnds) / Gia_ManAndNum(p) );
// printf( "Dom = %5d (%6.2f %%) ", Vec_IntSize(vDoms), 100.0 * Vec_IntSize(vDoms) / Gia_ManAndNum(p) );
printf( "\n" );
}
// cleanup
Vec_IntFree( vPis );
Vec_IntFree( vAnds );
Vec_IntFree( vSupp1 );
Vec_IntFree( vSupp2 );
// Gia_ManCleanMark1( p ); // this will erase markings
ABC_FREE( p->pRefs );
}
/**Function*************************************************************
Synopsis [Assumed that fMark1 marks the internal PIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_ManDupRpm( Gia_Man_t * p )
{
Vec_Int_t * vPis, * vAnds;
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
int i;
// derive PIs and internal nodes
vPis = Vec_IntAlloc( 100 );
vAnds = Vec_IntAlloc( 100 );
Gia_ManCountPisNodes( p, vPis, vAnds );
// duplicate AIG
Gia_ManFillValue( p );
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManConst0(p)->Value = 0;
// create PIs
Gia_ManForEachObjVec( vPis, p, pObj, i )
pObj->Value = Gia_ManAppendCi(pNew);
// create flops
Gia_ManForEachRo( p, pObj, i )
pObj->Value = Gia_ManAppendCi( pNew );
// create internal nodes
Gia_ManForEachObjVec( vAnds, p, pObj, i )
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
// create COs
Gia_ManForEachCo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
// cleanup
Vec_IntFree( vPis );
Vec_IntFree( vAnds );
return pNew;
}
/**Function*************************************************************
Synopsis [Performs structural reparametrization.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Abs_RpmPerform( Gia_Man_t * p, int nCutMax, int fVerbose, int fVeryVerbose )
{
Gia_Man_t * pNew;
// Gia_ManTestDoms( p );
// return NULL;
// perform structural analysis
Gia_ObjComputeTruthTableStart( p, nCutMax );
Abs_RpmPerformMark( p, nCutMax, fVerbose, fVeryVerbose );
Gia_ObjComputeTruthTableStop( p );
// derive new AIG
pNew = Gia_ManDupRpm( p );
Gia_ManCleanMark1( p );
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END