mirror of https://github.com/YosysHQ/abc.git
Fixed several important problems in choice computation (command 'dch').
This commit is contained in:
parent
73ab6aac1f
commit
7d29663720
|
|
@ -3475,10 +3475,6 @@ SOURCE=.\src\aig\gia\giaFront.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaGiarf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaGlitch.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
@ -3487,10 +3483,6 @@ SOURCE=.\src\aig\gia\giaHash.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaHcd.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaIf.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
|
|
@ -703,6 +703,7 @@ extern int Gia_ManCounterExampleValueLookup( Gia_Man_t * pGia, i
|
|||
/*=== giaChoice.c ============================================================*/
|
||||
extern void Gia_ManVerifyChoices( Gia_Man_t * p );
|
||||
extern void Gia_ManReverseClasses( Gia_Man_t * p, int fNowIncreasing );
|
||||
extern int Gia_ManHasChoices( Gia_Man_t * p );
|
||||
/*=== giaCsatOld.c ============================================================*/
|
||||
extern Vec_Int_t * Cbs_ManSolveMiter( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose );
|
||||
/*=== giaCsat.c ============================================================*/
|
||||
|
|
@ -914,7 +915,6 @@ extern int Gia_ObjIsMuxType( Gia_Obj_t * pNode );
|
|||
extern int Gia_ObjRecognizeExor( Gia_Obj_t * pObj, Gia_Obj_t ** ppFan0, Gia_Obj_t ** ppFan1 );
|
||||
extern Gia_Obj_t * Gia_ObjRecognizeMux( Gia_Obj_t * pNode, Gia_Obj_t ** ppNodeT, Gia_Obj_t ** ppNodeE );
|
||||
extern int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode );
|
||||
extern int Gia_ManHasChoices( Gia_Man_t * p );
|
||||
extern int Gia_ManHasDangling( Gia_Man_t * p );
|
||||
extern int Gia_ManMarkDangling( Gia_Man_t * p );
|
||||
extern Vec_Int_t * Gia_ManGetDangling( Gia_Man_t * p );
|
||||
|
|
|
|||
|
|
@ -51,28 +51,7 @@ void Gia_ManReverseClasses( Gia_Man_t * p, int fNowIncreasing )
|
|||
// collect classes
|
||||
vCollected = Vec_IntAlloc( 100 );
|
||||
Gia_ManForEachClass( p, iRepr )
|
||||
{
|
||||
Vec_IntPush( vCollected, iRepr );
|
||||
/*
|
||||
// check classes
|
||||
if ( !fNowIncreasing )
|
||||
{
|
||||
iPrev = iRepr;
|
||||
Gia_ClassForEachObj1( p, iRepr, iNode )
|
||||
{
|
||||
if ( iPrev < iNode )
|
||||
{
|
||||
printf( "Class %d : ", iRepr );
|
||||
Gia_ClassForEachObj( p, iRepr, iNode )
|
||||
printf( " %d", iNode );
|
||||
printf( "\n" );
|
||||
break;
|
||||
}
|
||||
iPrev = iNode;
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
// correct each class
|
||||
vClass = Vec_IntAlloc( 100 );
|
||||
Vec_IntForEachEntry( vCollected, iRepr, i )
|
||||
|
|
@ -83,14 +62,12 @@ void Gia_ManReverseClasses( Gia_Man_t * p, int fNowIncreasing )
|
|||
{
|
||||
if ( fNowIncreasing )
|
||||
assert( iRepr < iNode );
|
||||
// else
|
||||
// assert( iRepr > iNode );
|
||||
else
|
||||
assert( iRepr > iNode );
|
||||
Vec_IntPush( vClass, iNode );
|
||||
}
|
||||
if ( !fNowIncreasing )
|
||||
Vec_IntSort( vClass, 1 );
|
||||
// if ( iRepr == 129720 || iRepr == 129737 )
|
||||
// Vec_IntPrint( vClass );
|
||||
// if ( !fNowIncreasing )
|
||||
// Vec_IntSort( vClass, 1 );
|
||||
// reverse the class
|
||||
iPrev = 0;
|
||||
iRepr = Vec_IntEntryLast( vClass );
|
||||
|
|
@ -192,9 +169,10 @@ void Gia_ManCheckReprs( Gia_Man_t * p )
|
|||
printf( "GIA \"%s\": Representive verification successful.\n", Gia_ManName(p) );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find minimum level of each node using representatives.]
|
||||
Synopsis [Returns 1 if AIG has choices.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -203,290 +181,84 @@ void Gia_ManCheckReprs( Gia_Man_t * p )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManMinLevelRepr_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
|
||||
{
|
||||
int levMin, levCur, objId, reprId;
|
||||
// skip visited nodes
|
||||
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
|
||||
return Gia_ObjLevel(p, pObj);
|
||||
Gia_ObjSetTravIdCurrent(p, pObj);
|
||||
// skip CI nodes
|
||||
if ( Gia_ObjIsCi(pObj) )
|
||||
return Gia_ObjLevel(p, pObj);
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
objId = Gia_ObjId(p, pObj);
|
||||
if ( Gia_ObjIsNone(p, objId) )
|
||||
{
|
||||
// not part of the equivalence class
|
||||
Gia_ManMinLevelRepr_rec( p, Gia_ObjFanin0(pObj) );
|
||||
Gia_ManMinLevelRepr_rec( p, Gia_ObjFanin1(pObj) );
|
||||
Gia_ObjSetAndLevel( p, pObj );
|
||||
return Gia_ObjLevel(p, pObj);
|
||||
}
|
||||
// has equivalences defined
|
||||
assert( Gia_ObjHasRepr(p, objId) || Gia_ObjIsHead(p, objId) );
|
||||
reprId = Gia_ObjHasRepr(p, objId) ? Gia_ObjRepr(p, objId) : objId;
|
||||
// iterate through objects
|
||||
levMin = ABC_INFINITY;
|
||||
Gia_ClassForEachObj( p, reprId, objId )
|
||||
{
|
||||
levCur = Gia_ManMinLevelRepr_rec( p, Gia_ManObj(p, objId) );
|
||||
levMin = Abc_MinInt( levMin, levCur );
|
||||
}
|
||||
assert( levMin < ABC_INFINITY );
|
||||
// assign minimum level to all
|
||||
Gia_ClassForEachObj( p, reprId, objId )
|
||||
Gia_ObjSetLevelId( p, objId, levMin );
|
||||
return levMin;
|
||||
}
|
||||
int Gia_ManMinLevelRepr( Gia_Man_t * p )
|
||||
int Gia_ManHasChoices( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int i, LevelCur, LevelMax = 0;
|
||||
assert( Gia_ManRegNum(p) == 0 );
|
||||
Gia_ManCleanLevels( p, Gia_ManObjNum(p) );
|
||||
Gia_ManIncrementTravId( p );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
int i, Counter1 = 0, Counter2 = 0;
|
||||
int nFailNoRepr = 0;
|
||||
int nFailHaveRepr = 0;
|
||||
int nChoiceNodes = 0;
|
||||
int nChoices = 0;
|
||||
if ( p->pReprs == NULL || p->pNexts == NULL )
|
||||
return 0;
|
||||
// check if there are any representatives
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
assert( !Gia_ObjIsConst(p, i) );
|
||||
LevelCur = Gia_ManMinLevelRepr_rec( p, pObj );
|
||||
LevelMax = Abc_MaxInt( LevelMax, LevelCur );
|
||||
}
|
||||
printf( "Max level %d\n", LevelMax );
|
||||
return LevelMax;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns mapping of each old repr into new repr.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int * Gia_ManFindMinLevelMap( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int reprId, objId, levFan0, levFan1;
|
||||
int levMin, levMinOld, levMax, reprBest;
|
||||
int * pReprMap, * pMinLevels, iFanin;
|
||||
int i, fChange = 1;
|
||||
|
||||
Gia_ManLevelNum( p );
|
||||
pMinLevels = ABC_ALLOC( int, Gia_ManObjNum(p) );
|
||||
while ( fChange )
|
||||
{
|
||||
fChange = 0;
|
||||
// clean min-levels
|
||||
memset( pMinLevels, 0xFF, sizeof(int) * Gia_ManObjNum(p) );
|
||||
// for each class find min level
|
||||
Gia_ManForEachClass( p, reprId )
|
||||
if ( Gia_ObjReprObj( p, Gia_ObjId(p, pObj) ) )
|
||||
{
|
||||
levMin = ABC_INFINITY;
|
||||
Gia_ClassForEachObj( p, reprId, objId )
|
||||
levMin = Abc_MinInt( levMin, Gia_ObjLevelId(p, objId) );
|
||||
assert( levMin >= 0 && levMin < ABC_INFINITY );
|
||||
Gia_ClassForEachObj( p, reprId, objId )
|
||||
{
|
||||
assert( pMinLevels[objId] == -1 );
|
||||
pMinLevels[objId] = levMin;
|
||||
}
|
||||
// printf( "%d ", i );
|
||||
Counter1++;
|
||||
}
|
||||
// recompute levels
|
||||
levMax = 0;
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
// if ( Gia_ObjNext( p, Gia_ObjId(p, pObj) ) )
|
||||
// Counter2++;
|
||||
}
|
||||
// printf( "\n" );
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
// if ( Gia_ObjReprObj( p, Gia_ObjId(p, pObj) ) )
|
||||
// Counter1++;
|
||||
if ( Gia_ObjNext( p, Gia_ObjId(p, pObj) ) )
|
||||
{
|
||||
iFanin = Gia_ObjFaninId0(pObj, i);
|
||||
if ( Gia_ObjIsNone(p, iFanin) )
|
||||
levFan0 = Gia_ObjLevelId(p, iFanin);
|
||||
else if ( Gia_ObjIsConst(p, iFanin) )
|
||||
levFan0 = 0;
|
||||
else
|
||||
{
|
||||
assert( Gia_ObjIsClass( p, iFanin ) );
|
||||
assert( pMinLevels[iFanin] >= 0 );
|
||||
levFan0 = pMinLevels[iFanin];
|
||||
}
|
||||
|
||||
iFanin = Gia_ObjFaninId1(pObj, i);
|
||||
if ( Gia_ObjIsNone(p, iFanin) )
|
||||
levFan1 = Gia_ObjLevelId(p, iFanin);
|
||||
else if ( Gia_ObjIsConst(p, iFanin) )
|
||||
levFan1 = 0;
|
||||
else
|
||||
{
|
||||
assert( Gia_ObjIsClass( p, iFanin ) );
|
||||
assert( pMinLevels[iFanin] >= 0 );
|
||||
levFan1 = pMinLevels[iFanin];
|
||||
}
|
||||
levMinOld = Gia_ObjLevelId(p, i);
|
||||
levMin = 1 + Abc_MaxInt( levFan0, levFan1 );
|
||||
Gia_ObjSetLevelId( p, i, levMin );
|
||||
assert( levMin <= levMinOld );
|
||||
if ( levMin < levMinOld )
|
||||
fChange = 1;
|
||||
levMax = Abc_MaxInt( levMax, levMin );
|
||||
// printf( "%d ", i );
|
||||
Counter2++;
|
||||
}
|
||||
printf( "%d ", levMax );
|
||||
}
|
||||
ABC_FREE( pMinLevels );
|
||||
printf( "\n" );
|
||||
|
||||
// create repr map
|
||||
pReprMap = ABC_FALLOC( int, Gia_ManObjNum(p) );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( Gia_ObjIsConst(p, i) )
|
||||
pReprMap[i] = 0;
|
||||
Gia_ManForEachClass( p, reprId )
|
||||
// printf( "\n" );
|
||||
if ( Counter1 == 0 )
|
||||
{
|
||||
// find min-level repr
|
||||
reprBest = -1;
|
||||
levMin = ABC_INFINITY;
|
||||
Gia_ClassForEachObj( p, reprId, objId )
|
||||
if ( levMin > Gia_ObjLevelId(p, objId) )
|
||||
{
|
||||
levMin = Gia_ObjLevelId(p, objId);
|
||||
reprBest = objId;
|
||||
}
|
||||
assert( reprBest > 0 );
|
||||
Gia_ClassForEachObj( p, reprId, objId )
|
||||
pReprMap[objId] = reprBest;
|
||||
printf( "Warning: AIG has repr data-strucure but not reprs.\n" );
|
||||
return 0;
|
||||
}
|
||||
return pReprMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Find terminal AND nodes]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Int_t * Gia_ManDanglingAndNodes( Gia_Man_t * p )
|
||||
{
|
||||
Vec_Int_t * vTerms;
|
||||
Gia_Obj_t * pObj;
|
||||
int i;
|
||||
Gia_ManCleanMark0( p );
|
||||
printf( "%d nodes have reprs.\n", Counter1 );
|
||||
printf( "%d nodes have nexts.\n", Counter2 );
|
||||
// check if there are any internal nodes without fanout
|
||||
// make sure all nodes without fanout have representatives
|
||||
// make sure all nodes with fanout have no representatives
|
||||
ABC_FREE( p->pRefs );
|
||||
Gia_ManCreateRefs( p );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
Gia_ObjFanin0(pObj)->fMark0 = 1;
|
||||
Gia_ObjFanin1(pObj)->fMark1 = 1;
|
||||
if ( Gia_ObjRefs(p, pObj) == 0 )
|
||||
{
|
||||
if ( Gia_ObjReprObj( p, Gia_ObjId(p, pObj) ) == NULL )
|
||||
nFailNoRepr++;
|
||||
else
|
||||
nChoices++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Gia_ObjReprObj( p, Gia_ObjId(p, pObj) ) != NULL )
|
||||
nFailHaveRepr++;
|
||||
if ( Gia_ObjNextObj( p, Gia_ObjId(p, pObj) ) != NULL )
|
||||
nChoiceNodes++;
|
||||
}
|
||||
if ( Gia_ObjReprObj( p, i ) )
|
||||
assert( Gia_ObjRepr(p, i) < i );
|
||||
}
|
||||
vTerms = Vec_IntAlloc( 1000 );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
if ( !pObj->fMark0 )
|
||||
Vec_IntPush( vTerms, i );
|
||||
Gia_ManCleanMark0( p );
|
||||
return vTerms;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Reconstruct AIG starting with terminals.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManRebuidRepr_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, int * pReprMap )
|
||||
{
|
||||
int objId, reprLit = -1;
|
||||
if ( ~pObj->Value )
|
||||
return pObj->Value;
|
||||
assert( Gia_ObjIsAnd(pObj) );
|
||||
objId = Gia_ObjId( p, pObj );
|
||||
if ( Gia_ObjIsClass(p, objId) )
|
||||
if ( nChoices == 0 )
|
||||
return 0;
|
||||
if ( nFailNoRepr )
|
||||
{
|
||||
assert( pReprMap[objId] > 0 );
|
||||
reprLit = Gia_ManRebuidRepr_rec( pNew, p, Gia_ManObj(p, pReprMap[objId]), pReprMap );
|
||||
assert( reprLit > 1 );
|
||||
printf( "Gia_ManHasChoices(): Error: %d internal nodes have no fanout and no repr.\n", nFailNoRepr );
|
||||
// return 0;
|
||||
}
|
||||
else
|
||||
assert( Gia_ObjIsNone(p, objId) );
|
||||
Gia_ManRebuidRepr_rec( pNew, p, Gia_ObjFanin0(pObj), pReprMap );
|
||||
Gia_ManRebuidRepr_rec( pNew, p, Gia_ObjFanin1(pObj), pReprMap );
|
||||
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
assert( reprLit != (int)pObj->Value );
|
||||
if ( reprLit > 1 )
|
||||
pNew->pReprs[ Abc_Lit2Var(pObj->Value) ].iRepr = Abc_Lit2Var(reprLit);
|
||||
return pObj->Value;
|
||||
}
|
||||
Gia_Man_t * Gia_ManRebuidRepr( Gia_Man_t * p, int * pReprMap )
|
||||
{
|
||||
Vec_Int_t * vTerms;
|
||||
Gia_Man_t * pNew;
|
||||
Gia_Obj_t * pObj;
|
||||
int i;
|
||||
Gia_ManFillValue( p );
|
||||
pNew = Gia_ManStart( Gia_ManObjNum(p) );
|
||||
Gia_ManConst0(p)->Value = 0;
|
||||
Gia_ManForEachCi( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCi(pNew);
|
||||
vTerms = Gia_ManDanglingAndNodes( p );
|
||||
Gia_ManForEachObjVec( vTerms, p, pObj, i )
|
||||
Gia_ManRebuidRepr_rec( pNew, p, pObj, pReprMap );
|
||||
Vec_IntFree( vTerms );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
|
||||
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
|
||||
return pNew;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Aig_Man_t * Gia_ManNormalizeChoices( Aig_Man_t * pAig )
|
||||
{
|
||||
int * pReprMap;
|
||||
Aig_Man_t * pNew;
|
||||
Gia_Man_t * pGia, * pTemp;
|
||||
// create GIA with representatives
|
||||
assert( Aig_ManRegNum(pAig) == 0 );
|
||||
assert( pAig->pReprs != NULL );
|
||||
pGia = Gia_ManFromAigSimple( pAig );
|
||||
Gia_ManReprFromAigRepr2( pAig, pGia );
|
||||
// verify that representatives are correct
|
||||
Gia_ManCheckReprs( pGia );
|
||||
// find min-level repr for each class
|
||||
pReprMap = Gia_ManFindMinLevelMap( pGia );
|
||||
// reconstruct using correct order
|
||||
pGia = Gia_ManRebuidRepr( pTemp = pGia, pReprMap );
|
||||
Gia_ManStop( pTemp );
|
||||
ABC_FREE( pReprMap );
|
||||
// create choices
|
||||
|
||||
// verify that choices are correct
|
||||
// Gia_ManVerifyChoices( pGia );
|
||||
// copy the result back into AIG
|
||||
pNew = Gia_ManToAigSimple( pGia );
|
||||
Gia_ManReprToAigRepr( pNew, pGia );
|
||||
return pNew;
|
||||
}
|
||||
void Gia_ManNormalizeChoicesTest( Aig_Man_t * pAig )
|
||||
{
|
||||
Aig_Man_t * pNew = Gia_ManNormalizeChoices( pAig );
|
||||
Aig_ManStop( pNew );
|
||||
if ( nFailHaveRepr )
|
||||
{
|
||||
printf( "Gia_ManHasChoices(): Error: %d internal nodes have both fanout and repr.\n", nFailHaveRepr );
|
||||
// return 0;
|
||||
}
|
||||
// printf( "Gia_ManHasChoices(): AIG has %d choice nodes with %d choices.\n", nChoiceNodes, nChoices );
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -888,97 +888,6 @@ int Gia_NodeMffcSize( Gia_Man_t * p, Gia_Obj_t * pNode )
|
|||
return ConeSize1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if AIG has choices.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManHasChoices( Gia_Man_t * p )
|
||||
{
|
||||
Gia_Obj_t * pObj;
|
||||
int i, Counter1 = 0, Counter2 = 0;
|
||||
int nFailNoRepr = 0;
|
||||
int nFailHaveRepr = 0;
|
||||
int nChoiceNodes = 0;
|
||||
int nChoices = 0;
|
||||
if ( p->pReprs == NULL || p->pNexts == NULL )
|
||||
return 0;
|
||||
// check if there are any representatives
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjReprObj( p, Gia_ObjId(p, pObj) ) )
|
||||
{
|
||||
// printf( "%d ", i );
|
||||
Counter1++;
|
||||
}
|
||||
// if ( Gia_ObjNext( p, Gia_ObjId(p, pObj) ) )
|
||||
// Counter2++;
|
||||
}
|
||||
// printf( "\n" );
|
||||
Gia_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
// if ( Gia_ObjReprObj( p, Gia_ObjId(p, pObj) ) )
|
||||
// Counter1++;
|
||||
if ( Gia_ObjNext( p, Gia_ObjId(p, pObj) ) )
|
||||
{
|
||||
// printf( "%d ", i );
|
||||
Counter2++;
|
||||
}
|
||||
}
|
||||
// printf( "\n" );
|
||||
if ( Counter1 == 0 )
|
||||
{
|
||||
printf( "Warning: AIG has repr data-strucure but not reprs.\n" );
|
||||
return 0;
|
||||
}
|
||||
printf( "%d nodes have reprs.\n", Counter1 );
|
||||
printf( "%d nodes have nexts.\n", Counter2 );
|
||||
// check if there are any internal nodes without fanout
|
||||
// make sure all nodes without fanout have representatives
|
||||
// make sure all nodes with fanout have no representatives
|
||||
ABC_FREE( p->pRefs );
|
||||
Gia_ManCreateRefs( p );
|
||||
Gia_ManForEachAnd( p, pObj, i )
|
||||
{
|
||||
if ( Gia_ObjRefs(p, pObj) == 0 )
|
||||
{
|
||||
if ( Gia_ObjReprObj( p, Gia_ObjId(p, pObj) ) == NULL )
|
||||
nFailNoRepr++;
|
||||
else
|
||||
nChoices++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( Gia_ObjReprObj( p, Gia_ObjId(p, pObj) ) != NULL )
|
||||
nFailHaveRepr++;
|
||||
if ( Gia_ObjNextObj( p, Gia_ObjId(p, pObj) ) != NULL )
|
||||
nChoiceNodes++;
|
||||
}
|
||||
if ( Gia_ObjReprObj( p, i ) )
|
||||
assert( Gia_ObjRepr(p, i) < i );
|
||||
}
|
||||
if ( nChoices == 0 )
|
||||
return 0;
|
||||
if ( nFailNoRepr )
|
||||
{
|
||||
printf( "Gia_ManHasChoices(): Error: %d internal nodes have no fanout and no repr.\n", nFailNoRepr );
|
||||
// return 0;
|
||||
}
|
||||
if ( nFailHaveRepr )
|
||||
{
|
||||
printf( "Gia_ManHasChoices(): Error: %d internal nodes have both fanout and repr.\n", nFailHaveRepr );
|
||||
// return 0;
|
||||
}
|
||||
// printf( "Gia_ManHasChoices(): AIG has %d choice nodes with %d choices.\n", nChoiceNodes, nChoices );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns 1 if AIG has dangling nodes.]
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -31,6 +31,36 @@ ABC_NAMESPACE_IMPL_START
|
|||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts support nodes.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Dch_ObjCountSupp_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
int Count;
|
||||
if ( Aig_ObjIsTravIdCurrent( p, pObj ) )
|
||||
return 0;
|
||||
Aig_ObjSetTravIdCurrent( p, pObj );
|
||||
if ( Aig_ObjIsCi(pObj) )
|
||||
return 1;
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
Count = Dch_ObjCountSupp_rec( p, Aig_ObjFanin0(pObj) );
|
||||
Count += Dch_ObjCountSupp_rec( p, Aig_ObjFanin1(pObj) );
|
||||
return Count;
|
||||
}
|
||||
int Dch_ObjCountSupp( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
Aig_ManIncrementTravId( p );
|
||||
return Dch_ObjCountSupp_rec( p, pObj );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of representatives.]
|
||||
|
|
@ -56,54 +86,72 @@ int Dch_DeriveChoiceCountReprs( Aig_Man_t * pAig )
|
|||
}
|
||||
return nReprs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Counts the number of equivalences.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Dch_DeriveChoiceCountEquivs( Aig_Man_t * pAig )
|
||||
{
|
||||
Aig_Obj_t * pObj, * pTemp, * pPrev;
|
||||
int i, nEquivs = 0, Counter = 0;
|
||||
Aig_Obj_t * pObj, * pEquiv;
|
||||
int i, nEquivs = 0;
|
||||
Aig_ManForEachObj( pAig, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjIsChoice(pAig, pObj) )
|
||||
pEquiv = Aig_ObjEquiv( pAig, pObj );
|
||||
if ( pEquiv == NULL )
|
||||
continue;
|
||||
for ( pPrev = pObj, pTemp = Aig_ObjEquiv(pAig, pObj); pTemp;
|
||||
pPrev = pTemp, pTemp = Aig_ObjEquiv(pAig, pTemp) )
|
||||
{
|
||||
if ( pTemp->nRefs > 0 )
|
||||
{
|
||||
// remove referenced node from equivalence class
|
||||
assert( pAig->pEquivs[pPrev->Id] == pTemp );
|
||||
pAig->pEquivs[pPrev->Id] = pAig->pEquivs[pTemp->Id];
|
||||
pAig->pEquivs[pTemp->Id] = NULL;
|
||||
// how about the need to continue iterating over the list?
|
||||
// pPrev = pTemp ???
|
||||
Counter++;
|
||||
}
|
||||
nEquivs++;
|
||||
}
|
||||
assert( pEquiv->Id > pObj->Id );
|
||||
nEquivs++;
|
||||
}
|
||||
// printf( "Removed %d classes.\n", Counter );
|
||||
|
||||
if ( Counter )
|
||||
Dch_DeriveChoiceCountEquivs( pAig );
|
||||
// if ( Counter )
|
||||
// printf( "Removed %d equiv nodes because of non-zero ref counter.\n", Counter );
|
||||
return nEquivs;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Returns representatives of fanin in approapriate polarity.]
|
||||
Synopsis [Marks the TFI of the node.]
|
||||
|
||||
Description [Returns 1 if there is a CI not marked with previous ID.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Dch_ObjMarkTfi_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
int RetValue;
|
||||
if ( pObj == NULL )
|
||||
return 0;
|
||||
if ( Aig_ObjIsTravIdCurrent( p, pObj ) )
|
||||
return 0;
|
||||
if ( Aig_ObjIsCi(pObj) )
|
||||
{
|
||||
RetValue = !Aig_ObjIsTravIdPrevious( p, pObj );
|
||||
Aig_ObjSetTravIdCurrent( p, pObj );
|
||||
return RetValue;
|
||||
}
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
Aig_ObjSetTravIdCurrent( p, pObj );
|
||||
RetValue = Dch_ObjMarkTfi_rec( p, Aig_ObjFanin0(pObj) );
|
||||
RetValue += Dch_ObjMarkTfi_rec( p, Aig_ObjFanin1(pObj) );
|
||||
// RetValue += Dch_ObjMarkTfi_rec( p, Aig_ObjEquiv(p, pObj) );
|
||||
return (RetValue > 0);
|
||||
}
|
||||
int Dch_ObjCheckSuppRed( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pRepr )
|
||||
{
|
||||
// mark support of the representative node (pRepr)
|
||||
Aig_ManIncrementTravId( p );
|
||||
Dch_ObjMarkTfi_rec( p, pRepr );
|
||||
// detect if the new node (pObj) depends on additional variables
|
||||
Aig_ManIncrementTravId( p );
|
||||
if ( Dch_ObjMarkTfi_rec( p, pObj ) )
|
||||
return 1;//, printf( "1" );
|
||||
// detect if the representative node (pRepr) depends on additional variables
|
||||
Aig_ManIncrementTravId( p );
|
||||
if ( Dch_ObjMarkTfi_rec( p, pRepr ) )
|
||||
return 1;//, printf( "2" );
|
||||
// skip the choice if this is what is happening
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Make sure reprsentative nodes do not have representatives.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -112,19 +160,88 @@ int Dch_DeriveChoiceCountEquivs( Aig_Man_t * pAig )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
static inline Aig_Obj_t * Aig_ObjGetRepr( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
void Aig_ManCheckReprs( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pRepr;
|
||||
if ( (pRepr = Aig_ObjRepr(p, Aig_Regular(pObj))) )
|
||||
return Aig_NotCond( pRepr, Aig_Regular(pObj)->fPhase ^ pRepr->fPhase ^ Aig_IsComplement(pObj) );
|
||||
return pObj;
|
||||
int fPrintConst = 0;
|
||||
Aig_Obj_t * pObj;
|
||||
int i, fProb = 0;
|
||||
int Class0 = 0, ClassCi = 0;
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( Aig_ObjRepr(p, pObj) == NULL )
|
||||
continue;
|
||||
if ( !Aig_ObjIsNode(pObj) )
|
||||
printf( "Obj %d is not an AND but it has a repr %d.\n", i, Aig_ObjId(Aig_ObjRepr(p, pObj)) ), fProb = 1;
|
||||
else if ( Aig_ObjRepr(p, Aig_ObjRepr(p, pObj)) )
|
||||
printf( "Obj %d has repr %d with a repr %d.\n", i, Aig_ObjId(Aig_ObjRepr(p, pObj)), Aig_ObjId(Aig_ObjRepr(p, Aig_ObjRepr(p, pObj))) ), fProb = 1;
|
||||
}
|
||||
if ( !fProb )
|
||||
printf( "Representive verification successful.\n" );
|
||||
else
|
||||
printf( "Representive verification FAILED.\n" );
|
||||
if ( !fPrintConst )
|
||||
return;
|
||||
// count how many representatives are const0 or a CI
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( Aig_ObjRepr(p, pObj) == Aig_ManConst1(p) )
|
||||
Class0++;
|
||||
if ( Aig_ObjRepr(p, pObj) && Aig_ObjIsCi(Aig_ObjRepr(p, pObj)) )
|
||||
ClassCi++;
|
||||
}
|
||||
printf( "Const0 nodes = %d. ConstCI nodes = %d.\n", Class0, ClassCi );
|
||||
}
|
||||
|
||||
static inline Aig_Obj_t * Aig_ObjChild0CopyRepr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjGetRepr( p, Aig_ObjChild0Copy(pObj) ); }
|
||||
static inline Aig_Obj_t * Aig_ObjChild1CopyRepr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjGetRepr( p, Aig_ObjChild1Copy(pObj) ); }
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Verify correctness of choices.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Dch_CheckChoices( Aig_Man_t * p, int fSkipRedSupps )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, fProb = 0;
|
||||
Aig_ManCleanMarkA( p );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
{
|
||||
if ( p->pEquivs[i] != NULL )
|
||||
{
|
||||
if ( pObj->fMarkA == 1 )
|
||||
printf( "node %d participates in more than one choice class\n", i ), fProb = 1;
|
||||
pObj->fMarkA = 1;
|
||||
// check redundancy
|
||||
if ( fSkipRedSupps && Dch_ObjCheckSuppRed( p, pObj, p->pEquivs[i]) )
|
||||
printf( "node %d and repr %d have diff supports\n", pObj->Id, p->pEquivs[i]->Id );
|
||||
// consider the next one
|
||||
pObj = p->pEquivs[i];
|
||||
if ( p->pEquivs[Aig_ObjId(pObj)] == NULL )
|
||||
{
|
||||
if ( pObj->fMarkA == 1 )
|
||||
printf( "repr %d has final node %d participates in more than one choice class\n", i, pObj->Id ), fProb = 1;
|
||||
pObj->fMarkA = 1;
|
||||
}
|
||||
// consider the non-head ones
|
||||
if ( pObj->nRefs > 0 )
|
||||
printf( "node %d belonging to choice has fanout %d\n", pObj->Id, pObj->nRefs );
|
||||
}
|
||||
if ( p->pReprs && p->pReprs[i] != NULL )
|
||||
{
|
||||
if ( pObj->nRefs > 0 )
|
||||
printf( "node %d has representative %d and fanout count %d\n", pObj->Id, p->pReprs[i]->Id, pObj->nRefs ), fProb = 1;
|
||||
}
|
||||
}
|
||||
Aig_ManCleanMarkA( p );
|
||||
if ( !fProb )
|
||||
printf( "Verification of choice AIG succeeded.\n" );
|
||||
else
|
||||
printf( "Verification of choice AIG FAILED.\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -240,104 +357,6 @@ int Aig_ManCheckAcyclic( Aig_Man_t * p, int fVerbose )
|
|||
return fAcyclic;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Removes combinational loop.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Aig_ManFixLoopProblem( Aig_Man_t * p, int fVerbose )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, Counter = 0, Counter2 = 0;
|
||||
Aig_ManForEachObj( p, pObj, i )
|
||||
{
|
||||
if ( !Aig_ObjIsTravIdCurrent(p, pObj) )
|
||||
continue;
|
||||
Counter2++;
|
||||
if ( Aig_ObjRepr(p, pObj) == NULL && Aig_ObjEquiv(p, pObj) != NULL )
|
||||
{
|
||||
Aig_ObjSetEquiv(p, pObj, NULL);
|
||||
Counter++;
|
||||
}
|
||||
}
|
||||
if ( fVerbose )
|
||||
Abc_Print( 1, "Fixed %d choice nodes on the path with %d objects.\n", Counter, Counter2 );
|
||||
}
|
||||
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Verify correctness of choices.]
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Dch_CheckChoices( Aig_Man_t * p )
|
||||
{
|
||||
Aig_Obj_t * pObj;
|
||||
int i, fProb = 0;
|
||||
Aig_ManCleanMarkA( p );
|
||||
Aig_ManForEachNode( p, pObj, i )
|
||||
if ( p->pEquivs[i] != NULL )
|
||||
{
|
||||
if ( pObj->fMarkA == 1 )
|
||||
printf( "node %d participates in more than one choice class\n", i ), fProb = 1;
|
||||
pObj->fMarkA = 1;
|
||||
// consider the last one
|
||||
pObj = p->pEquivs[i];
|
||||
if ( p->pEquivs[Aig_ObjId(pObj)] == NULL )
|
||||
{
|
||||
if ( pObj->fMarkA == 1 )
|
||||
printf( "repr %d has final node %d participates in more than one choice class\n", i, pObj->Id ), fProb = 1;
|
||||
pObj->fMarkA = 1;
|
||||
}
|
||||
}
|
||||
Aig_ManCleanMarkA( p );
|
||||
if ( !fProb )
|
||||
printf( "Verification of choice AIG succeeded.\n" );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Marks the TFI of the node.]
|
||||
|
||||
Description [Returns 1 if there is a CI not marked with previous ID.]
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Dch_ObjMarkTfi_rec( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
int RetValue;
|
||||
if ( pObj == NULL )
|
||||
return 0;
|
||||
if ( Aig_ObjIsTravIdCurrent( p, pObj ) )
|
||||
return 0;
|
||||
if ( Aig_ObjIsCi(pObj) )
|
||||
{
|
||||
RetValue = !Aig_ObjIsTravIdPrevious( p, pObj );
|
||||
Aig_ObjSetTravIdCurrent( p, pObj );
|
||||
return RetValue;
|
||||
}
|
||||
assert( Aig_ObjIsNode(pObj) );
|
||||
Aig_ObjSetTravIdCurrent( p, pObj );
|
||||
RetValue = Dch_ObjMarkTfi_rec( p, Aig_ObjFanin0(pObj) );
|
||||
RetValue += Dch_ObjMarkTfi_rec( p, Aig_ObjFanin1(pObj) );
|
||||
// RetValue += Dch_ObjMarkTfi_rec( p, Aig_ObjEquiv(p, pObj) );
|
||||
return (RetValue > 0);
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -391,7 +410,7 @@ int Dch_ObjCheckTfi( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pRepr )
|
|||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis [Derives the AIG with choices from representatives.]
|
||||
Synopsis [Returns representatives of fanin in approapriate polarity.]
|
||||
|
||||
Description []
|
||||
|
||||
|
|
@ -400,91 +419,15 @@ int Dch_ObjCheckTfi( Aig_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pRepr )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Dch_DeriveChoiceAigNode( Aig_Man_t * pAigNew, Aig_Man_t * pAigOld, Aig_Obj_t * pObj, int fSkipRedSupps )
|
||||
static inline Aig_Obj_t * Aig_ObjGetRepr( Aig_Man_t * p, Aig_Obj_t * pObj )
|
||||
{
|
||||
Aig_Obj_t * pRepr, * pObjNew, * pReprNew;
|
||||
// get the new node
|
||||
assert( pObj->pData == NULL );
|
||||
pObj->pData = Aig_And( pAigNew,
|
||||
Aig_ObjChild0CopyRepr(pAigNew, pObj),
|
||||
Aig_ObjChild1CopyRepr(pAigNew, pObj) );
|
||||
pRepr = Aig_ObjRepr( pAigOld, pObj );
|
||||
if ( pRepr == NULL )
|
||||
return;
|
||||
assert( pRepr->Id < pObj->Id );
|
||||
// get the corresponding new nodes
|
||||
pObjNew = Aig_Regular((Aig_Obj_t *)pObj->pData);
|
||||
pReprNew = Aig_Regular((Aig_Obj_t *)pRepr->pData);
|
||||
if ( pObjNew == pReprNew )
|
||||
return;
|
||||
// skip the earlier nodes
|
||||
if ( pReprNew->Id > pObjNew->Id )
|
||||
return;
|
||||
assert( pReprNew->Id < pObjNew->Id );
|
||||
// set the representatives
|
||||
Aig_ObjSetRepr( pAigNew, pObjNew, pReprNew );
|
||||
// skip used nodes
|
||||
if ( pObjNew->nRefs > 0 )
|
||||
return;
|
||||
assert( pObjNew->nRefs == 0 );
|
||||
// update new nodes of the object
|
||||
if ( !Aig_ObjIsNode(pRepr) )
|
||||
return;
|
||||
// skip choices with combinational loops
|
||||
if ( Dch_ObjCheckTfi( pAigNew, pObjNew, pReprNew ) )
|
||||
return;
|
||||
// don't add choice if structural support of pObjNew and pReprNew differ
|
||||
if ( fSkipRedSupps )
|
||||
{
|
||||
int fSkipChoice = 0;
|
||||
// mark support of the representative node (pReprNew)
|
||||
Aig_ManIncrementTravId( pAigNew );
|
||||
Dch_ObjMarkTfi_rec( pAigNew, pReprNew );
|
||||
// detect if the new node (pObjNew) depends on any additional variables
|
||||
Aig_ManIncrementTravId( pAigNew );
|
||||
if ( Dch_ObjMarkTfi_rec( pAigNew, pObjNew ) )
|
||||
fSkipChoice = 1;//, printf( "1" );
|
||||
// detect if the representative node (pReprNew) depends on any additional variables
|
||||
Aig_ManIncrementTravId( pAigNew );
|
||||
if ( Dch_ObjMarkTfi_rec( pAigNew, pReprNew ) )
|
||||
fSkipChoice = 1;//, printf( "2" );
|
||||
// skip the choice if this is what is happening
|
||||
if ( fSkipChoice )
|
||||
return;
|
||||
}
|
||||
// add choice
|
||||
pAigNew->pEquivs[pObjNew->Id] = pAigNew->pEquivs[pReprNew->Id];
|
||||
pAigNew->pEquivs[pReprNew->Id] = pObjNew;
|
||||
}
|
||||
Aig_Man_t * Dch_DeriveChoiceAigInt( Aig_Man_t * pAig, int fSkipRedSupps )
|
||||
{
|
||||
Aig_Man_t * pChoices;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
// make sure reprsentative nodes do not have representatives
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
if ( pAig->pReprs[i] != NULL && pAig->pReprs[pAig->pReprs[i]->Id] != NULL )
|
||||
printf( "Node %d: repr %d has repr %d.\n", i, Aig_ObjId(pAig->pReprs[i]), Aig_ObjId(pAig->pReprs[pAig->pReprs[i]->Id]) );
|
||||
// start recording equivalences
|
||||
pChoices = Aig_ManStart( Aig_ManObjNumMax(pAig) );
|
||||
pChoices->pEquivs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) );
|
||||
pChoices->pReprs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) );
|
||||
// map constants and PIs
|
||||
Aig_ManCleanData( pAig );
|
||||
Aig_ManConst1(pAig)->pData = Aig_ManConst1(pChoices);
|
||||
Aig_ManForEachCi( pAig, pObj, i )
|
||||
pObj->pData = Aig_ObjCreateCi( pChoices );
|
||||
// construct choices for the internal nodes
|
||||
assert( pAig->pReprs != NULL );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
Dch_DeriveChoiceAigNode( pChoices, pAig, pObj, fSkipRedSupps );
|
||||
Aig_ManForEachCo( pAig, pObj, i )
|
||||
Aig_ObjCreateCo( pChoices, Aig_ObjChild0CopyRepr(pChoices, pObj) );
|
||||
Dch_DeriveChoiceCountEquivs( pChoices );
|
||||
Aig_ManSetRegNum( pChoices, Aig_ManRegNum(pAig) );
|
||||
//Dch_CheckChoices( pChoices );
|
||||
return pChoices;
|
||||
Aig_Obj_t * pRepr;
|
||||
if ( (pRepr = Aig_ObjRepr(p, Aig_Regular(pObj))) )
|
||||
return Aig_NotCond( pRepr, Aig_Regular(pObj)->fPhase ^ pRepr->fPhase ^ Aig_IsComplement(pObj) );
|
||||
return pObj;
|
||||
}
|
||||
static inline Aig_Obj_t * Aig_ObjChild0CopyRepr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjGetRepr( p, Aig_ObjChild0Copy(pObj) ); }
|
||||
static inline Aig_Obj_t * Aig_ObjChild1CopyRepr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjGetRepr( p, Aig_ObjChild1Copy(pObj) ); }
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
|
|
@ -497,24 +440,99 @@ Aig_Man_t * Dch_DeriveChoiceAigInt( Aig_Man_t * pAig, int fSkipRedSupps )
|
|||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
void Dch_DeriveChoiceAigNode( Aig_Man_t * pAigNew, Aig_Man_t * pAigOld, Aig_Obj_t * pObj, int fSkipRedSupps )
|
||||
{
|
||||
Aig_Obj_t * pRepr, * pObjNew, * pReprNew;
|
||||
assert( !Aig_IsComplement(pObj) );
|
||||
// get the representative
|
||||
pRepr = Aig_ObjRepr( pAigOld, pObj );
|
||||
if ( pRepr != NULL && (Aig_ObjIsConst1(pRepr) || Aig_ObjIsCi(pRepr)) )
|
||||
{
|
||||
assert( pRepr->pData != NULL );
|
||||
pObj->pData = Aig_NotCond( (Aig_Obj_t *)pRepr->pData, pObj->fPhase ^ pRepr->fPhase );
|
||||
return;
|
||||
}
|
||||
// get the new node
|
||||
pObjNew = Aig_And( pAigNew,
|
||||
Aig_ObjChild0CopyRepr(pAigNew, pObj),
|
||||
Aig_ObjChild1CopyRepr(pAigNew, pObj) );
|
||||
pObjNew = Aig_ObjGetRepr( pAigNew, pObjNew );
|
||||
assert( Aig_ObjRepr( pAigNew, pObjNew ) == NULL );
|
||||
// assign the copy
|
||||
assert( pObj->pData == NULL );
|
||||
pObj->pData = pObjNew;
|
||||
// skip those without reprs
|
||||
if ( pRepr == NULL )
|
||||
return;
|
||||
assert( pRepr->Id < pObj->Id );
|
||||
assert( Aig_ObjIsNode(pRepr) );
|
||||
// get the corresponding new nodes
|
||||
pObjNew = Aig_Regular((Aig_Obj_t *)pObj->pData);
|
||||
pReprNew = Aig_Regular((Aig_Obj_t *)pRepr->pData);
|
||||
// skip earlier nodes
|
||||
if ( pReprNew->Id >= pObjNew->Id )
|
||||
return;
|
||||
assert( pReprNew->Id < pObjNew->Id );
|
||||
// set the representatives
|
||||
Aig_ObjSetRepr( pAigNew, pObjNew, pReprNew );
|
||||
// skip used nodes
|
||||
if ( pObjNew->nRefs > 0 )
|
||||
return;
|
||||
assert( pObjNew->nRefs == 0 );
|
||||
// skip choices that can lead to combo loops
|
||||
if ( Dch_ObjCheckTfi( pAigNew, pObjNew, pReprNew ) )
|
||||
return;
|
||||
// don't add choice if structural support of pObjNew and pReprNew differ
|
||||
if ( fSkipRedSupps && Dch_ObjCheckSuppRed(pAigNew, pObjNew, pReprNew) )
|
||||
return;
|
||||
// add choice to the end of the list
|
||||
while ( pAigNew->pEquivs[pReprNew->Id] != NULL )
|
||||
pReprNew = pAigNew->pEquivs[pReprNew->Id];
|
||||
assert( pAigNew->pEquivs[pReprNew->Id] == NULL );
|
||||
pAigNew->pEquivs[pReprNew->Id] = pObjNew;
|
||||
}
|
||||
Aig_Man_t * Dch_DeriveChoiceAigInt( Aig_Man_t * pAig, int fSkipRedSupps )
|
||||
{
|
||||
Aig_Man_t * pChoices;
|
||||
Aig_Obj_t * pObj;
|
||||
int i;
|
||||
// start recording equivalences
|
||||
pChoices = Aig_ManStart( Aig_ManObjNumMax(pAig) );
|
||||
pChoices->pEquivs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) );
|
||||
pChoices->pReprs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) );
|
||||
// map constants and PIs
|
||||
Aig_ManCleanData( pAig );
|
||||
Aig_ManConst1(pAig)->pData = Aig_ManConst1(pChoices);
|
||||
Aig_ManForEachCi( pAig, pObj, i )
|
||||
pObj->pData = Aig_ObjCreateCi( pChoices );
|
||||
// construct choices for the internal nodes
|
||||
assert( pAig->pReprs != NULL );
|
||||
Aig_ManForEachNode( pAig, pObj, i )
|
||||
Dch_DeriveChoiceAigNode( pChoices, pAig, pObj, fSkipRedSupps );
|
||||
Aig_ManForEachCo( pAig, pObj, i )
|
||||
Aig_ObjCreateCo( pChoices, Aig_ObjChild0CopyRepr(pChoices, pObj) );
|
||||
Aig_ManSetRegNum( pChoices, Aig_ManRegNum(pAig) );
|
||||
return pChoices;
|
||||
}
|
||||
Aig_Man_t * Dch_DeriveChoiceAig( Aig_Man_t * pAig, int fSkipRedSupps )
|
||||
{
|
||||
extern int Aig_ManCheckAcyclic( Aig_Man_t * pAig, int fVerbose );
|
||||
int fCheck = 0;
|
||||
Aig_Man_t * pChoices, * pTemp;
|
||||
int fVerbose = 0;
|
||||
// verify
|
||||
if ( fCheck )
|
||||
Aig_ManCheckReprs( pAig );
|
||||
// compute choices
|
||||
pChoices = Dch_DeriveChoiceAigInt( pAig, fSkipRedSupps );
|
||||
// pChoices = Dch_DeriveChoiceAigInt( pTemp = pChoices );
|
||||
// Aig_ManStop( pTemp );
|
||||
// there is no need for cleanup
|
||||
ABC_FREE( pChoices->pReprs );
|
||||
while ( !Aig_ManCheckAcyclic( pChoices, fVerbose ) )
|
||||
{
|
||||
if ( fVerbose )
|
||||
Abc_Print( 1, "There is a loop!\n" );
|
||||
Aig_ManFixLoopProblem( pChoices, fVerbose );
|
||||
}
|
||||
// verify
|
||||
if ( fCheck )
|
||||
Dch_CheckChoices( pChoices, fSkipRedSupps );
|
||||
// find correct topo order with choices
|
||||
pChoices = Aig_ManDupDfs( pTemp = pChoices );
|
||||
Aig_ManStop( pTemp );
|
||||
// verify
|
||||
if ( fCheck )
|
||||
Dch_CheckChoices( pChoices, fSkipRedSupps );
|
||||
return pChoices;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -106,19 +106,13 @@ p->timeSimInit = clock() - clk;
|
|||
// free memory ahead of time
|
||||
p->timeTotal = clock() - clkTotal;
|
||||
Dch_ManStop( p );
|
||||
// try something different
|
||||
{
|
||||
// extern void Gia_ManNormalizeChoicesTest( Aig_Man_t * pAig );
|
||||
// Gia_ManNormalizeChoicesTest( pAig );
|
||||
}
|
||||
|
||||
// create choices
|
||||
ABC_FREE( pAig->pTable );
|
||||
pResult = Dch_DeriveChoiceAig( pAig, pPars->fSkipRedSupp );
|
||||
// count the number of representatives
|
||||
if ( pPars->fVerbose )
|
||||
Abc_Print( 1, "STATS: Reprs = %6d. Equivs = %6d. Choices = %6d.\n",
|
||||
Dch_DeriveChoiceCountReprs( pAig ),
|
||||
Dch_DeriveChoiceCountReprs( pResult ),
|
||||
Dch_DeriveChoiceCountEquivs( pResult ),
|
||||
Aig_ManChoiceNum( pResult ) );
|
||||
return pResult;
|
||||
|
|
|
|||
Loading…
Reference in New Issue