mirror of https://github.com/YosysHQ/abc.git
346 lines
11 KiB
C
346 lines
11 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [giaSweep.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Scalable AIG package.]
|
|
|
|
Synopsis [Sweeping of GIA manager.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: giaSweep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "gia.h"
|
|
#include "giaAig.h"
|
|
#include "proof/dch/dch.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Mark GIA nodes that feed into POs.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Gia_ManFraigCheckCis( Gia_Man_t * p, Gia_Obj_t * pObj )
|
|
{
|
|
for ( assert( Gia_ObjIsCi(pObj) ); Gia_ObjIsCi(pObj); pObj-- )
|
|
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
|
return 1;
|
|
return 0;
|
|
}
|
|
Gia_Obj_t * Gia_ManFraigMarkCis( Gia_Man_t * p, Gia_Obj_t * pObj, int fMark )
|
|
{
|
|
for ( assert( Gia_ObjIsCi(pObj) ); Gia_ObjIsCi(pObj); pObj-- )
|
|
if ( fMark )
|
|
Gia_ObjSetTravIdCurrent( p, pObj );
|
|
return pObj;
|
|
}
|
|
Gia_Obj_t * Gia_ManFraigMarkCos( Gia_Man_t * p, Gia_Obj_t * pObj, int fMark )
|
|
{
|
|
for ( assert( Gia_ObjIsCo(pObj) ); Gia_ObjIsCo(pObj); pObj-- )
|
|
if ( fMark )
|
|
{
|
|
Gia_ObjSetTravIdCurrent( p, pObj );
|
|
Gia_ObjSetTravIdCurrent( p, Gia_ObjFanin0(pObj) );
|
|
}
|
|
return pObj;
|
|
}
|
|
Gia_Obj_t * Gia_ManFraigMarkAnd( Gia_Man_t * p, Gia_Obj_t * pObj )
|
|
{
|
|
for ( assert( Gia_ObjIsAnd(pObj) ); Gia_ObjIsAnd(pObj); pObj-- )
|
|
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
|
{
|
|
Gia_ObjSetTravIdCurrent( p, Gia_ObjFanin0(pObj) );
|
|
Gia_ObjSetTravIdCurrent( p, Gia_ObjFanin1(pObj) );
|
|
}
|
|
return pObj;
|
|
}
|
|
Gia_Man_t * Gia_ManFraigCreateGia( Gia_Man_t * p )
|
|
{
|
|
Vec_Int_t * vBoxPres;
|
|
Gia_Man_t * pNew;
|
|
Gia_Obj_t * pObj;
|
|
int i, fLabelPos;
|
|
assert( p->pManTime != NULL );
|
|
// start marks
|
|
Gia_ManIncrementTravId( p );
|
|
Gia_ObjSetTravIdCurrent( p, Gia_ManConst0(p) );
|
|
vBoxPres = Vec_IntAlloc( 1000 );
|
|
// mark primary outputs
|
|
fLabelPos = 1;
|
|
pObj = Gia_ManObj( p, Gia_ManObjNum(p) - 1 );
|
|
assert( Gia_ObjIsCo(pObj) );
|
|
while ( Gia_ObjIsCo(pObj) )
|
|
{
|
|
pObj = Gia_ManFraigMarkCos( p, pObj, fLabelPos );
|
|
if ( Gia_ObjIsAnd(pObj) )
|
|
pObj = Gia_ManFraigMarkAnd( p, pObj );
|
|
assert( Gia_ObjIsCi(pObj) );
|
|
fLabelPos = Gia_ManFraigCheckCis(p, pObj);
|
|
pObj = Gia_ManFraigMarkCis( p, pObj, fLabelPos );
|
|
Vec_IntPush( vBoxPres, fLabelPos );
|
|
}
|
|
Vec_IntPop( vBoxPres );
|
|
Vec_IntReverseOrder( vBoxPres );
|
|
assert( Gia_ObjIsConst0(pObj) );
|
|
// mark primary inputs
|
|
Gia_ManForEachObj1( p, pObj, i )
|
|
if ( Gia_ObjIsCi(pObj) )
|
|
Gia_ObjSetTravIdCurrent( p, pObj );
|
|
else
|
|
break;
|
|
// duplicate marked entries
|
|
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
|
pNew->pName = Abc_UtilStrsav( p->pName );
|
|
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
|
Gia_ManConst0(p)->Value = 0;
|
|
Gia_ManForEachObj1( p, pObj, i )
|
|
{
|
|
if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
|
|
continue;
|
|
if ( Gia_ObjIsCi(pObj) )
|
|
pObj->Value = Gia_ManAppendCi(pNew);
|
|
else if ( Gia_ObjIsAnd(pObj) )
|
|
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
|
else if ( Gia_ObjIsCo(pObj) )
|
|
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
|
else assert( 0 );
|
|
}
|
|
// update timing manager
|
|
pNew->pManTime = Gia_ManUpdateTimMan( p, vBoxPres );
|
|
// update extra STG
|
|
assert( p->pAigExtra != NULL );
|
|
assert( pNew->pAigExtra == NULL );
|
|
pNew->pAigExtra = Gia_ManUpdateExtraAig( p->pManTime, p->pAigExtra, vBoxPres );
|
|
Vec_IntFree( vBoxPres );
|
|
// assert( Gia_ManPiNum(pNew) == Tim_ManCiNum(pNew->pManTime) );
|
|
// assert( Gia_ManPoNum(pNew) == Tim_ManCoNum(pNew->pManTime) );
|
|
// assert( Gia_ManPiNum(pNew) == Tim_ManPiNum(pNew->pManTime) + Gia_ManPoNum(pNew->pAigExtra) );
|
|
return pNew;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Duplicates the AIG in the DFS order.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Gia_ObjFanin0CopyRepr( Gia_Man_t * p, Gia_Obj_t * pObj, int * pReprs )
|
|
{
|
|
int fanId = Gia_ObjFaninId0p( p, pObj );
|
|
if ( pReprs[fanId] == -1 )
|
|
return Gia_ObjFanin0Copy( pObj );
|
|
assert( Abc_Lit2Var(pReprs[fanId]) < Gia_ObjId(p, pObj) );
|
|
return Abc_LitNotCond( Gia_ObjValue(Gia_ManObj(p, Abc_Lit2Var(pReprs[fanId]))), Gia_ObjFaninC0(pObj) ^ Abc_LitIsCompl(pReprs[fanId]) );
|
|
}
|
|
int Gia_ObjFanin1CopyRepr( Gia_Man_t * p, Gia_Obj_t * pObj, int * pReprs )
|
|
{
|
|
int fanId = Gia_ObjFaninId1p( p, pObj );
|
|
if ( pReprs[fanId] == -1 )
|
|
return Gia_ObjFanin1Copy( pObj );
|
|
assert( Abc_Lit2Var(pReprs[fanId]) < Gia_ObjId(p, pObj) );
|
|
return Abc_LitNotCond( Gia_ObjValue(Gia_ManObj(p, Abc_Lit2Var(pReprs[fanId]))), Gia_ObjFaninC1(pObj) ^ Abc_LitIsCompl(pReprs[fanId]) );
|
|
}
|
|
Gia_Man_t * Gia_ManFraigReduceGia( Gia_Man_t * p, int * pReprs )
|
|
{
|
|
Gia_Man_t * pNew;
|
|
Gia_Obj_t * pObj;
|
|
int i;
|
|
assert( pReprs != NULL );
|
|
assert( Gia_ManRegNum(p) == 0 );
|
|
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
|
pNew->pName = Abc_UtilStrsav( p->pName );
|
|
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
|
|
Gia_ManFillValue( p );
|
|
Gia_ManHashAlloc( pNew );
|
|
Gia_ManForEachObj( p, pObj, i )
|
|
{
|
|
if ( Gia_ObjIsAnd(pObj) )
|
|
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0CopyRepr(p, pObj, pReprs), Gia_ObjFanin1CopyRepr(p, pObj, pReprs) );
|
|
else if ( Gia_ObjIsCi(pObj) )
|
|
pObj->Value = Gia_ManAppendCi( pNew );
|
|
else if ( Gia_ObjIsCo(pObj) )
|
|
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0CopyRepr(p, pObj, pReprs) );
|
|
else if ( Gia_ObjIsConst0(pObj) )
|
|
pObj->Value = 0;
|
|
else assert( 0 );
|
|
}
|
|
Gia_ManHashStop( pNew );
|
|
return pNew;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Computes representatives in terms of the original objects.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pGia, int fVerbose )
|
|
{
|
|
Gia_Obj_t * pObj;
|
|
int * pReprs = ABC_FALLOC( int, Gia_ManObjNum(p) );
|
|
int * pGia2Abc = ABC_FALLOC( int, Gia_ManObjNum(pGia) );
|
|
int i, iLitGia, iLitGia2, iReprGia, fCompl;
|
|
int nConsts = 0, nReprs = 0;
|
|
pGia2Abc[0] = 0;
|
|
Gia_ManSetPhase( pGia );
|
|
Gia_ManForEachObj1( p, pObj, i )
|
|
{
|
|
if ( Gia_ObjIsCo(pObj) )
|
|
continue;
|
|
assert( Gia_ObjIsCi(pObj) || Gia_ObjIsAnd(pObj) );
|
|
iLitGia = Gia_ObjValue(pObj);
|
|
if ( iLitGia == -1 )
|
|
continue;
|
|
iReprGia = Gia_ObjReprSelf( pGia, Abc_Lit2Var(iLitGia) );
|
|
if ( pGia2Abc[iReprGia] == -1 )
|
|
pGia2Abc[iReprGia] = i;
|
|
else
|
|
{
|
|
iLitGia2 = Gia_ObjValue( Gia_ManObj(p, pGia2Abc[iReprGia]) );
|
|
assert( Gia_ObjReprSelf(pGia, Abc_Lit2Var(iLitGia)) == Gia_ObjReprSelf(pGia, Abc_Lit2Var(iLitGia2)) );
|
|
fCompl = Abc_LitIsCompl(iLitGia) ^ Abc_LitIsCompl(iLitGia2);
|
|
fCompl ^= Gia_ManObj(pGia, Abc_Lit2Var(iLitGia))->fPhase;
|
|
fCompl ^= Gia_ManObj(pGia, Abc_Lit2Var(iLitGia2))->fPhase;
|
|
pReprs[i] = Abc_Var2Lit( pGia2Abc[iReprGia], fCompl );
|
|
assert( Abc_Lit2Var(pReprs[i]) < i );
|
|
if ( pGia2Abc[iReprGia] == 0 )
|
|
nConsts++;
|
|
else
|
|
nReprs++;
|
|
}
|
|
}
|
|
ABC_FREE( pGia2Abc );
|
|
if ( fVerbose )
|
|
printf( "Found %d const reprs and %d other reprs.\n", nConsts, nReprs );
|
|
return pReprs;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Gia_ManFraigSweepPerform( Gia_Man_t * p, void * pPars )
|
|
{
|
|
Aig_Man_t * pNew;
|
|
pNew = Gia_ManToAigSimple( p );
|
|
assert( Gia_ManObjNum(p) == Aig_ManObjNum(pNew) );
|
|
Dch_ComputeEquivalences( pNew, (Dch_Pars_t *)pPars );
|
|
Gia_ManReprFromAigRepr( pNew, p );
|
|
Aig_ManStop( pNew );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Reduces root model with scorr.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Gia_Man_t * Gia_ManFraigSweep( Gia_Man_t * p, void * pPars )
|
|
{
|
|
Gia_Man_t * pGia, * pNew, * pTemp;
|
|
int * pReprs;
|
|
assert( Gia_ManRegNum(p) == 0 );
|
|
if ( p->pManTime == NULL )
|
|
{
|
|
Gia_ManFraigSweepPerform( p, pPars );
|
|
pNew = Gia_ManEquivReduce( p, 1, 0, 0, 0 );
|
|
if ( pNew == NULL )
|
|
return Gia_ManDup(p);
|
|
return pNew;
|
|
}
|
|
if ( p->pAigExtra == NULL )
|
|
{
|
|
printf( "Timing manager is given but there is no GIA of boxes.\n" );
|
|
return NULL;
|
|
}
|
|
// order AIG objects
|
|
pNew = Gia_ManDupUnnormalize( p );
|
|
if ( pNew == NULL )
|
|
return NULL;
|
|
// find global equivalences
|
|
pNew->pManTime = p->pManTime;
|
|
pGia = Gia_ManDupCollapse( pNew, p->pAigExtra, NULL );
|
|
pNew->pManTime = NULL;
|
|
Gia_ManFraigSweepPerform( pGia, pPars );
|
|
// transfer equivalences
|
|
pReprs = Gia_ManFraigSelectReprs( pNew, pGia, ((Dch_Pars_t *)pPars)->fVerbose );
|
|
Gia_ManStop( pGia );
|
|
// reduce AIG
|
|
pNew = Gia_ManFraigReduceGia( pTemp = pNew, pReprs );
|
|
Gia_ManStop( pTemp );
|
|
ABC_FREE( pReprs );
|
|
// derive new AIG
|
|
assert( pNew->pManTime == NULL );
|
|
assert( pNew->pAigExtra == NULL );
|
|
pNew->pManTime = p->pManTime;
|
|
pNew->pAigExtra = p->pAigExtra;
|
|
pNew->nAnd2Delay = p->nAnd2Delay;
|
|
pNew = Gia_ManFraigCreateGia( pTemp = pNew );
|
|
assert( pTemp->pManTime == p->pManTime );
|
|
assert( pTemp->pAigExtra == p->pAigExtra );
|
|
pTemp->pManTime = NULL;
|
|
pTemp->pAigExtra = NULL;
|
|
Gia_ManStop( pTemp );
|
|
// normalize the result
|
|
pNew = Gia_ManDupNormalize( pTemp = pNew );
|
|
Gia_ManTransferTiming( pNew, pTemp );
|
|
Gia_ManStop( pTemp );
|
|
// return the result
|
|
assert( pNew->pManTime != NULL );
|
|
assert( pNew->pAigExtra != NULL );
|
|
return pNew;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|