Commit ddc6d1c1 by Alan Mishchenko

Version abc70828

parent 28467823
...@@ -2586,6 +2586,10 @@ SOURCE=.\src\aig\fra\fraInd.c ...@@ -2586,6 +2586,10 @@ SOURCE=.\src\aig\fra\fraInd.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\aig\fra\fraLcr.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\fra\fraMan.c SOURCE=.\src\aig\fra\fraMan.c
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -2794,6 +2798,10 @@ SOURCE=.\src\aig\aig\aigRet.c ...@@ -2794,6 +2798,10 @@ SOURCE=.\src\aig\aig\aigRet.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\aig\aig\aigScl.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\aig\aigSeq.c SOURCE=.\src\aig\aig\aigSeq.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -128,6 +128,8 @@ struct Aig_Man_t_ ...@@ -128,6 +128,8 @@ struct Aig_Man_t_
int fCatchExor; // enables EXOR nodes int fCatchExor; // enables EXOR nodes
int fAddStrash; // performs additional strashing int fAddStrash; // performs additional strashing
Aig_Obj_t ** pObjCopies; // mapping of AIG nodes into FRAIG nodes Aig_Obj_t ** pObjCopies; // mapping of AIG nodes into FRAIG nodes
void (*pImpFunc) (void*, void*); // implication checking precedure
void * pImpData; // implication checking data
// timing statistics // timing statistics
int time1; int time1;
int time2; int time2;
...@@ -298,6 +300,9 @@ static inline void Aig_ManRecycleMemory( Aig_Man_t * p, Aig_Obj_t * pEntry ) ...@@ -298,6 +300,9 @@ static inline void Aig_ManRecycleMemory( Aig_Man_t * p, Aig_Obj_t * pEntry )
// iterator over the primary outputs // iterator over the primary outputs
#define Aig_ManForEachPo( p, pObj, i ) \ #define Aig_ManForEachPo( p, pObj, i ) \
Vec_PtrForEachEntry( p->vPos, pObj, i ) Vec_PtrForEachEntry( p->vPos, pObj, i )
// iterator over the assertions
#define Aig_ManForEachAssert( p, pObj, i ) \
Vec_PtrForEachEntryStart( p->vPos, pObj, i, Aig_ManPoNum(p)-p->nAsserts )
// iterator over all objects, including those currently not used // iterator over all objects, including those currently not used
#define Aig_ManForEachObj( p, pObj, i ) \ #define Aig_ManForEachObj( p, pObj, i ) \
Vec_PtrForEachEntry( p->vObjs, pObj, i ) if ( (pObj) == NULL ) {} else Vec_PtrForEachEntry( p->vObjs, pObj, i ) if ( (pObj) == NULL ) {} else
...@@ -373,15 +378,12 @@ extern void Aig_ManFanoutStop( Aig_Man_t * p ); ...@@ -373,15 +378,12 @@ extern void Aig_ManFanoutStop( Aig_Man_t * p );
/*=== aigMan.c ==========================================================*/ /*=== aigMan.c ==========================================================*/
extern Aig_Man_t * Aig_ManStart( int nNodesMax ); extern Aig_Man_t * Aig_ManStart( int nNodesMax );
extern Aig_Man_t * Aig_ManStartFrom( Aig_Man_t * p ); extern Aig_Man_t * Aig_ManStartFrom( Aig_Man_t * p );
extern Aig_Obj_t * Aig_ManDup_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj );
extern Aig_Man_t * Aig_ManDup( Aig_Man_t * p, int fOrdered ); extern Aig_Man_t * Aig_ManDup( Aig_Man_t * p, int fOrdered );
extern Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap );
extern Aig_Man_t * Aig_ManExtractMiter( Aig_Man_t * p, Aig_Obj_t * pNode1, Aig_Obj_t * pNode2 ); extern Aig_Man_t * Aig_ManExtractMiter( Aig_Man_t * p, Aig_Obj_t * pNode1, Aig_Obj_t * pNode2 );
extern void Aig_ManStop( Aig_Man_t * p ); extern void Aig_ManStop( Aig_Man_t * p );
extern int Aig_ManCleanup( Aig_Man_t * p ); extern int Aig_ManCleanup( Aig_Man_t * p );
extern int Aig_ManCountMergeRegs( Aig_Man_t * p );
extern int Aig_ManSeqCleanup( Aig_Man_t * p );
extern void Aig_ManPrintStats( Aig_Man_t * p ); extern void Aig_ManPrintStats( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose );
/*=== aigMem.c ==========================================================*/ /*=== aigMem.c ==========================================================*/
extern void Aig_ManStartMemory( Aig_Man_t * p ); extern void Aig_ManStartMemory( Aig_Man_t * p );
extern void Aig_ManStopMemory( Aig_Man_t * p ); extern void Aig_ManStopMemory( Aig_Man_t * p );
...@@ -436,6 +438,11 @@ extern Aig_Man_t * Aig_ManRehash( Aig_Man_t * p ); ...@@ -436,6 +438,11 @@ extern Aig_Man_t * Aig_ManRehash( Aig_Man_t * p );
extern void Aig_ManCreateChoices( Aig_Man_t * p ); extern void Aig_ManCreateChoices( Aig_Man_t * p );
/*=== aigRet.c ========================================================*/ /*=== aigRet.c ========================================================*/
extern Aig_Man_t * Rtm_ManRetime( Aig_Man_t * p, int fForward, int nStepsMax, int fVerbose ); extern Aig_Man_t * Rtm_ManRetime( Aig_Man_t * p, int fForward, int nStepsMax, int fVerbose );
/*=== aigScl.c ==========================================================*/
extern Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap );
extern int Aig_ManSeqCleanup( Aig_Man_t * p );
extern int Aig_ManCountMergeRegs( Aig_Man_t * p );
extern Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose );
/*=== aigSeq.c ========================================================*/ /*=== aigSeq.c ========================================================*/
extern int Aig_ManSeqStrash( Aig_Man_t * p, int nLatches, int * pInits ); extern int Aig_ManSeqStrash( Aig_Man_t * p, int nLatches, int * pInits );
/*=== aigShow.c ========================================================*/ /*=== aigShow.c ========================================================*/
......
...@@ -172,54 +172,6 @@ Aig_Man_t * Aig_ManDup( Aig_Man_t * p, int fOrdered ) ...@@ -172,54 +172,6 @@ Aig_Man_t * Aig_ManDup( Aig_Man_t * p, int fOrdered )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Remaps the manager.]
Description [Map in the array specifies for each CI nodes the node that
should be used after remapping.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj, * pObjMapped;
int i;
// create the new manager
pNew = Aig_ManStart( Aig_ManObjIdMax(p) + 1 );
pNew->nRegs = p->nRegs;
pNew->nAsserts = p->nAsserts;
// create the PIs
Aig_ManCleanData( p );
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
Aig_ManForEachPi( p, pObj, i )
pObj->pData = Aig_ObjCreatePi(pNew);
// implement the mapping
Aig_ManForEachPi( p, pObj, i )
{
pObjMapped = Vec_PtrEntry( vMap, i );
pObj->pData = Aig_NotCond( Aig_Regular(pObjMapped)->pData, Aig_IsComplement(pObjMapped) );
}
// duplicate internal nodes
Aig_ManForEachObj( p, pObj, i )
if ( Aig_ObjIsBuf(pObj) )
pObj->pData = Aig_ObjChild0Copy(pObj);
else if ( Aig_ObjIsNode(pObj) )
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
// add the POs
Aig_ManForEachPo( p, pObj, i )
Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
assert( Aig_ManNodeNum(p) >= Aig_ManNodeNum(pNew) );
// check the resulting network
if ( !Aig_ManCheck(pNew) )
printf( "Aig_ManDup(): The check has failed.\n" );
return pNew;
}
/**Function*************************************************************
Synopsis [Extracts the miter composed of XOR of the two nodes.] Synopsis [Extracts the miter composed of XOR of the two nodes.]
Description [] Description []
...@@ -306,110 +258,6 @@ void Aig_ManStop( Aig_Man_t * p ) ...@@ -306,110 +258,6 @@ void Aig_ManStop( Aig_Man_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Aig_ManSeqCleanup_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
return;
Aig_ObjSetTravIdCurrent(p, pObj);
// collect latch input corresponding to unmarked PI (latch output)
if ( Aig_ObjIsPi(pObj) )
{
Vec_PtrPush( vNodes, pObj->pNext );
return;
}
if ( Aig_ObjIsPo(pObj) )
{
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin0(pObj), vNodes );
return;
}
assert( Aig_ObjIsNode(pObj) );
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin0(pObj), vNodes );
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin1(pObj), vNodes );
}
/**Function*************************************************************
Synopsis [Returns the number of dangling nodes removed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManSeqCleanup( Aig_Man_t * p )
{
Vec_Ptr_t * vNodes, * vCis, * vCos;
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int i, nTruePis, nTruePos;
assert( Aig_ManBufNum(p) == 0 );
// mark the PIs
Aig_ManIncrementTravId( p );
Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) );
Aig_ManForEachPiSeq( p, pObj, i )
Aig_ObjSetTravIdCurrent( p, pObj );
// prepare to collect nodes reachable from POs
vNodes = Vec_PtrAlloc( 100 );
Aig_ManForEachPoSeq( p, pObj, i )
Vec_PtrPush( vNodes, pObj );
// remember latch inputs in latch outputs
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
pObjLo->pNext = pObjLi;
// mark the nodes reachable from these nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
Aig_ManSeqCleanup_rec( p, pObj, vNodes );
assert( Vec_PtrSize(vNodes) <= Aig_ManPoNum(p) );
// clean latch output pointers
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
pObjLo->pNext = NULL;
// if some latches are removed, update PIs/POs
if ( Vec_PtrSize(vNodes) < Aig_ManPoNum(p) )
{
// collect new CIs/COs
vCis = Vec_PtrAlloc( Aig_ManPiNum(p) );
Aig_ManForEachPi( p, pObj, i )
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
Vec_PtrPush( vCis, pObj );
vCos = Vec_PtrAlloc( Aig_ManPoNum(p) );
Aig_ManForEachPo( p, pObj, i )
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
Vec_PtrPush( vCos, pObj );
else
Aig_ObjDisconnect( p, pObj );
// remember the number of true PIs/POs
nTruePis = Aig_ManPiNum(p) - Aig_ManRegNum(p);
nTruePos = Aig_ManPoNum(p) - Aig_ManRegNum(p);
// set the new number of registers
p->nRegs -= Aig_ManPoNum(p) - Vec_PtrSize(vNodes);
// create new PIs/POs
assert( Vec_PtrSize(vCis) == nTruePis + p->nRegs );
assert( Vec_PtrSize(vCos) == nTruePos + p->nRegs );
Vec_PtrFree( p->vPis ); p->vPis = vCis;
Vec_PtrFree( p->vPos ); p->vPos = vCos;
p->nObjs[AIG_OBJ_PI] = Vec_PtrSize( p->vPis );
p->nObjs[AIG_OBJ_PO] = Vec_PtrSize( p->vPos );
}
Vec_PtrFree( vNodes );
// remove dangling nodes
return Aig_ManCleanup( p );
}
/**Function*************************************************************
Synopsis [Returns the number of dangling nodes removed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManCleanup( Aig_Man_t * p ) int Aig_ManCleanup( Aig_Man_t * p )
{ {
Vec_Ptr_t * vObjs; Vec_Ptr_t * vObjs;
...@@ -430,42 +278,6 @@ int Aig_ManCleanup( Aig_Man_t * p ) ...@@ -430,42 +278,6 @@ int Aig_ManCleanup( Aig_Man_t * p )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Returns the number of dangling nodes removed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManCountMergeRegs( Aig_Man_t * p )
{
Aig_Obj_t * pObj, * pFanin;
int i, Counter = 0, Const0 = 0, Const1 = 0;
Aig_ManIncrementTravId( p );
Aig_ManForEachLiSeq( p, pObj, i )
{
pFanin = Aig_ObjFanin0(pObj);
if ( Aig_ObjIsConst1(pFanin) )
{
if ( Aig_ObjFaninC0(pObj) )
Const0++;
else
Const1++;
}
if ( Aig_ObjIsTravIdCurrent(p, pFanin) )
continue;
Aig_ObjSetTravIdCurrent(p, pFanin);
Counter++;
}
printf( "Regs = %d. Fanins = %d. Const0 = %d. Const1 = %d.\n",
Aig_ManRegNum(p), Counter, Const0, Const1 );
return 0;
}
/**Function*************************************************************
Synopsis [Stops the AIG manager.] Synopsis [Stops the AIG manager.]
Description [] Description []
...@@ -491,149 +303,6 @@ void Aig_ManPrintStats( Aig_Man_t * p ) ...@@ -491,149 +303,6 @@ void Aig_ManPrintStats( Aig_Man_t * p )
printf( "\n" ); printf( "\n" );
} }
/**Function*************************************************************
Synopsis [Checks how many latches can be reduced.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManReduceLachesCount( Aig_Man_t * p )
{
Aig_Obj_t * pObj, * pFanin;
int i, Counter = 0;
assert( Aig_ManRegNum(p) > 0 );
Aig_ManForEachObj( p, pObj, i )
assert( !pObj->fMarkA && !pObj->fMarkB );
Aig_ManForEachLiSeq( p, pObj, i )
{
pFanin = Aig_ObjFanin0(pObj);
if ( Aig_ObjFaninC0(pObj) )
{
if ( pFanin->fMarkB )
Counter++;
else
pFanin->fMarkB = 1;
}
else
{
if ( pFanin->fMarkA )
Counter++;
else
pFanin->fMarkA = 1;
}
}
Aig_ManForEachLiSeq( p, pObj, i )
{
pFanin = Aig_ObjFanin0(pObj);
pFanin->fMarkA = pFanin->fMarkB = 0;
}
return Counter;
}
/**Function*************************************************************
Synopsis [Reduces the latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Aig_ManReduceLachesOnce( Aig_Man_t * p )
{
Vec_Ptr_t * vMap;
Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pFanin;
int * pMapping, i;
// start mapping by adding the true PIs
vMap = Vec_PtrAlloc( Aig_ManPiNum(p) );
Aig_ManForEachPiSeq( p, pObj, i )
Vec_PtrPush( vMap, pObj );
// create mapping of fanin nodes into the corresponding latch outputs
pMapping = ALLOC( int, 2 * (Aig_ManObjIdMax(p) + 1) );
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
{
pFanin = Aig_ObjFanin0(pObjLi);
if ( Aig_ObjFaninC0(pObjLi) )
{
if ( pFanin->fMarkB )
{
Vec_PtrPush( vMap, Aig_ManLo(p, pMapping[2*pFanin->Id + 1]) );
}
else
{
pFanin->fMarkB = 1;
pMapping[2*pFanin->Id + 1] = i;
Vec_PtrPush( vMap, pObjLo );
}
}
else
{
if ( pFanin->fMarkA )
{
Vec_PtrPush( vMap, Aig_ManLo(p, pMapping[2*pFanin->Id]) );
}
else
{
pFanin->fMarkA = 1;
pMapping[2*pFanin->Id] = i;
Vec_PtrPush( vMap, pObjLo );
}
}
}
free( pMapping );
Aig_ManForEachLiSeq( p, pObj, i )
{
pFanin = Aig_ObjFanin0(pObj);
pFanin->fMarkA = pFanin->fMarkB = 0;
}
return vMap;
}
/**Function*************************************************************
Synopsis [Reduces the latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose )
{
Aig_Man_t * pTemp;
Vec_Ptr_t * vMap;
int nSaved, nCur;
for ( nSaved = 0; nCur = Aig_ManReduceLachesCount(p); nSaved += nCur )
{
if ( fVerbose )
{
printf( "Saved = %5d. ", nCur );
printf( "RBeg = %5d. NBeg = %6d. ", Aig_ManRegNum(p), Aig_ManNodeNum(p) );
}
vMap = Aig_ManReduceLachesOnce( p );
p = Aig_ManRemap( pTemp = p, vMap );
Aig_ManStop( pTemp );
Vec_PtrFree( vMap );
Aig_ManSeqCleanup( p );
if ( fVerbose )
{
printf( "REnd = %5d. NEnd = %6d. ", Aig_ManRegNum(p), Aig_ManNodeNum(p) );
printf( "\n" );
}
}
return p;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -321,7 +321,7 @@ Vec_Vec_t * Aig_ManSupports( Aig_Man_t * pMan ) ...@@ -321,7 +321,7 @@ Vec_Vec_t * Aig_ManSupports( Aig_Man_t * pMan )
} }
assert( 0 ); assert( 0 );
} }
printf( "Memory usage = %d Mb.\n", Vec_PtrSize(p->vMemory) * p->nChunkSize / (1<<20) ); //printf( "Memory usage = %d Mb.\n", Vec_PtrSize(p->vMemory) * p->nChunkSize / (1<<20) );
Part_ManStop( p ); Part_ManStop( p );
// sort supports by size // sort supports by size
Vec_VecSort( vSupps, 1 ); Vec_VecSort( vSupps, 1 );
......
...@@ -253,7 +253,7 @@ Aig_Obj_t * Aig_ManDupRepr_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pOb ...@@ -253,7 +253,7 @@ Aig_Obj_t * Aig_ManDupRepr_rec( Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pOb
***********************************************************************/ ***********************************************************************/
Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p ) Aig_Man_t * Aig_ManDupRepr( Aig_Man_t * p )
{ {
int fOrdered = 1; int fOrdered = 0;
Aig_Man_t * pNew; Aig_Man_t * pNew;
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
int i; int i;
......
/**CFile****************************************************************
FileName [aigScl.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [AIG package.]
Synopsis [Sequential cleanup.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - April 28, 2007.]
Revision [$Id: aigScl.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
***********************************************************************/
#include "aig.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Remaps the manager.]
Description [Map in the array specifies for each CI nodes the node that
should be used after remapping.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManRemap( Aig_Man_t * p, Vec_Ptr_t * vMap )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj, * pObjMapped;
int i;
// create the new manager
pNew = Aig_ManStart( Aig_ManObjIdMax(p) + 1 );
pNew->nRegs = p->nRegs;
pNew->nAsserts = p->nAsserts;
// create the PIs
Aig_ManCleanData( p );
Aig_ManConst1(p)->pData = Aig_ManConst1(pNew);
Aig_ManForEachPi( p, pObj, i )
pObj->pData = Aig_ObjCreatePi(pNew);
// implement the mapping
Aig_ManForEachPi( p, pObj, i )
{
pObjMapped = Vec_PtrEntry( vMap, i );
pObj->pData = Aig_NotCond( Aig_Regular(pObjMapped)->pData, Aig_IsComplement(pObjMapped) );
}
// duplicate internal nodes
Aig_ManForEachObj( p, pObj, i )
if ( Aig_ObjIsBuf(pObj) )
pObj->pData = Aig_ObjChild0Copy(pObj);
else if ( Aig_ObjIsNode(pObj) )
pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
// add the POs
Aig_ManForEachPo( p, pObj, i )
Aig_ObjCreatePo( pNew, Aig_ObjChild0Copy(pObj) );
assert( Aig_ManNodeNum(p) >= Aig_ManNodeNum(pNew) );
// check the resulting network
if ( !Aig_ManCheck(pNew) )
printf( "Aig_ManDup(): The check has failed.\n" );
return pNew;
}
/**Function*************************************************************
Synopsis [Returns the number of dangling nodes removed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_ManSeqCleanup_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vNodes )
{
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
return;
Aig_ObjSetTravIdCurrent(p, pObj);
// collect latch input corresponding to unmarked PI (latch output)
if ( Aig_ObjIsPi(pObj) )
{
Vec_PtrPush( vNodes, pObj->pNext );
return;
}
if ( Aig_ObjIsPo(pObj) )
{
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin0(pObj), vNodes );
return;
}
assert( Aig_ObjIsNode(pObj) );
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin0(pObj), vNodes );
Aig_ManSeqCleanup_rec( p, Aig_ObjFanin1(pObj), vNodes );
}
/**Function*************************************************************
Synopsis [Returns the number of dangling nodes removed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManSeqCleanup( Aig_Man_t * p )
{
Vec_Ptr_t * vNodes, * vCis, * vCos;
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int i, nTruePis, nTruePos;
assert( Aig_ManBufNum(p) == 0 );
// mark the PIs
Aig_ManIncrementTravId( p );
Aig_ObjSetTravIdCurrent( p, Aig_ManConst1(p) );
Aig_ManForEachPiSeq( p, pObj, i )
Aig_ObjSetTravIdCurrent( p, pObj );
// prepare to collect nodes reachable from POs
vNodes = Vec_PtrAlloc( 100 );
Aig_ManForEachPoSeq( p, pObj, i )
Vec_PtrPush( vNodes, pObj );
// remember latch inputs in latch outputs
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
pObjLo->pNext = pObjLi;
// mark the nodes reachable from these nodes
Vec_PtrForEachEntry( vNodes, pObj, i )
Aig_ManSeqCleanup_rec( p, pObj, vNodes );
assert( Vec_PtrSize(vNodes) <= Aig_ManPoNum(p) );
// clean latch output pointers
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
pObjLo->pNext = NULL;
// if some latches are removed, update PIs/POs
if ( Vec_PtrSize(vNodes) < Aig_ManPoNum(p) )
{
// collect new CIs/COs
vCis = Vec_PtrAlloc( Aig_ManPiNum(p) );
Aig_ManForEachPi( p, pObj, i )
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
Vec_PtrPush( vCis, pObj );
vCos = Vec_PtrAlloc( Aig_ManPoNum(p) );
Aig_ManForEachPo( p, pObj, i )
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
Vec_PtrPush( vCos, pObj );
else
Aig_ObjDisconnect( p, pObj );
// remember the number of true PIs/POs
nTruePis = Aig_ManPiNum(p) - Aig_ManRegNum(p);
nTruePos = Aig_ManPoNum(p) - Aig_ManRegNum(p);
// set the new number of registers
p->nRegs -= Aig_ManPoNum(p) - Vec_PtrSize(vNodes);
// create new PIs/POs
assert( Vec_PtrSize(vCis) == nTruePis + p->nRegs );
assert( Vec_PtrSize(vCos) == nTruePos + p->nRegs );
Vec_PtrFree( p->vPis ); p->vPis = vCis;
Vec_PtrFree( p->vPos ); p->vPos = vCos;
p->nObjs[AIG_OBJ_PI] = Vec_PtrSize( p->vPis );
p->nObjs[AIG_OBJ_PO] = Vec_PtrSize( p->vPos );
}
Vec_PtrFree( vNodes );
// remove dangling nodes
return Aig_ManCleanup( p );
}
/**Function*************************************************************
Synopsis [Returns the number of dangling nodes removed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManCountMergeRegs( Aig_Man_t * p )
{
Aig_Obj_t * pObj, * pFanin;
int i, Counter = 0, Const0 = 0, Const1 = 0;
Aig_ManIncrementTravId( p );
Aig_ManForEachLiSeq( p, pObj, i )
{
pFanin = Aig_ObjFanin0(pObj);
if ( Aig_ObjIsConst1(pFanin) )
{
if ( Aig_ObjFaninC0(pObj) )
Const0++;
else
Const1++;
}
if ( Aig_ObjIsTravIdCurrent(p, pFanin) )
continue;
Aig_ObjSetTravIdCurrent(p, pFanin);
Counter++;
}
printf( "Regs = %d. Fanins = %d. Const0 = %d. Const1 = %d.\n",
Aig_ManRegNum(p), Counter, Const0, Const1 );
return 0;
}
/**Function*************************************************************
Synopsis [Checks how many latches can be reduced.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Aig_ManReduceLachesCount( Aig_Man_t * p )
{
Aig_Obj_t * pObj, * pFanin;
int i, Counter = 0, Diffs = 0;
assert( Aig_ManRegNum(p) > 0 );
Aig_ManForEachObj( p, pObj, i )
assert( !pObj->fMarkA && !pObj->fMarkB );
Aig_ManForEachLiSeq( p, pObj, i )
{
pFanin = Aig_ObjFanin0(pObj);
if ( Aig_ObjFaninC0(pObj) )
{
if ( pFanin->fMarkB )
Counter++;
else
pFanin->fMarkB = 1;
}
else
{
if ( pFanin->fMarkA )
Counter++;
else
pFanin->fMarkA = 1;
}
}
// count fanins that have both attributes
Aig_ManForEachLiSeq( p, pObj, i )
{
pFanin = Aig_ObjFanin0(pObj);
Diffs += pFanin->fMarkA && pFanin->fMarkB;
pFanin->fMarkA = pFanin->fMarkB = 0;
}
// printf( "Diffs = %d.\n", Diffs );
return Counter;
}
/**Function*************************************************************
Synopsis [Reduces the latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Aig_ManReduceLachesOnce( Aig_Man_t * p )
{
Vec_Ptr_t * vMap;
Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pFanin;
int * pMapping, i;
// start mapping by adding the true PIs
vMap = Vec_PtrAlloc( Aig_ManPiNum(p) );
Aig_ManForEachPiSeq( p, pObj, i )
Vec_PtrPush( vMap, pObj );
// create mapping of fanin nodes into the corresponding latch outputs
pMapping = ALLOC( int, 2 * (Aig_ManObjIdMax(p) + 1) );
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
{
pFanin = Aig_ObjFanin0(pObjLi);
if ( Aig_ObjFaninC0(pObjLi) )
{
if ( pFanin->fMarkB )
{
Vec_PtrPush( vMap, Aig_ManLo(p, pMapping[2*pFanin->Id + 1]) );
}
else
{
pFanin->fMarkB = 1;
pMapping[2*pFanin->Id + 1] = i;
Vec_PtrPush( vMap, pObjLo );
}
}
else
{
if ( pFanin->fMarkA )
{
Vec_PtrPush( vMap, Aig_ManLo(p, pMapping[2*pFanin->Id]) );
}
else
{
pFanin->fMarkA = 1;
pMapping[2*pFanin->Id] = i;
Vec_PtrPush( vMap, pObjLo );
}
}
}
free( pMapping );
Aig_ManForEachLiSeq( p, pObj, i )
{
pFanin = Aig_ObjFanin0(pObj);
pFanin->fMarkA = pFanin->fMarkB = 0;
}
return vMap;
}
/**Function*************************************************************
Synopsis [Reduces the latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Aig_ManReduceLaches( Aig_Man_t * p, int fVerbose )
{
Aig_Man_t * pTemp;
Vec_Ptr_t * vMap;
int nSaved, nCur;
for ( nSaved = 0; nCur = Aig_ManReduceLachesCount(p); nSaved += nCur )
{
if ( fVerbose )
{
printf( "Saved = %5d. ", nCur );
printf( "RBeg = %5d. NBeg = %6d. ", Aig_ManRegNum(p), Aig_ManNodeNum(p) );
}
vMap = Aig_ManReduceLachesOnce( p );
p = Aig_ManRemap( pTemp = p, vMap );
Aig_ManStop( pTemp );
Vec_PtrFree( vMap );
Aig_ManSeqCleanup( p );
if ( fVerbose )
{
printf( "REnd = %5d. NEnd = %6d. ", Aig_ManRegNum(p), Aig_ManNodeNum(p) );
printf( "\n" );
}
}
return p;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#define TSI_MAX_ROUNDS 10000 #define TSI_MAX_ROUNDS 1000
#define AIG_XVS0 1 #define AIG_XVS0 1
#define AIG_XVS1 2 #define AIG_XVS1 2
...@@ -340,7 +340,7 @@ Vec_Ptr_t * Aig_ManTernarySimulate( Aig_Man_t * p, int fVerbose ) ...@@ -340,7 +340,7 @@ Vec_Ptr_t * Aig_ManTernarySimulate( Aig_Man_t * p, int fVerbose )
} }
if ( f == TSI_MAX_ROUNDS ) if ( f == TSI_MAX_ROUNDS )
{ {
printf( "Aig_ManTernarySimulate(): Did not reach a fixed point after %d iterations.\n", TSI_MAX_ROUNDS ); printf( "Aig_ManTernarySimulate(): Did not reach a fixed point after %d iterations (not a bug).\n", TSI_MAX_ROUNDS );
Aig_TsiStop( pTsi ); Aig_TsiStop( pTsi );
return NULL; return NULL;
} }
......
...@@ -662,7 +662,7 @@ void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName ) ...@@ -662,7 +662,7 @@ void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName )
{ {
FILE * pFile; FILE * pFile;
Vec_Ptr_t * vNodes; Vec_Ptr_t * vNodes;
Aig_Obj_t * pObj, * pConst1 = NULL; Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pConst1 = NULL;
int i, nDigits, Counter = 0; int i, nDigits, Counter = 0;
if ( Aig_ManPoNum(p) == 0 ) if ( Aig_ManPoNum(p) == 0 )
{ {
...@@ -687,14 +687,22 @@ void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName ) ...@@ -687,14 +687,22 @@ void Aig_ManDumpBlif( Aig_Man_t * p, char * pFileName )
fprintf( pFile, ".model test\n" ); fprintf( pFile, ".model test\n" );
// write PIs // write PIs
fprintf( pFile, ".inputs" ); fprintf( pFile, ".inputs" );
Aig_ManForEachPi( p, pObj, i ) Aig_ManForEachPiSeq( p, pObj, i )
fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData ); fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
fprintf( pFile, "\n" ); fprintf( pFile, "\n" );
// write POs // write POs
fprintf( pFile, ".outputs" ); fprintf( pFile, ".outputs" );
Aig_ManForEachPo( p, pObj, i ) Aig_ManForEachPoSeq( p, pObj, i )
fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData ); fprintf( pFile, " n%0*d", nDigits, (int)pObj->pData );
fprintf( pFile, "\n" ); fprintf( pFile, "\n" );
// write latches
if ( Aig_ManRegNum(p) )
{
fprintf( pFile, "\n" );
Aig_ManForEachLiLoSeq( p, pObjLi, pObjLo, i )
fprintf( pFile, ".latch n%0*d n%0*d 0\n", nDigits, (int)pObjLi->pData, nDigits, (int)pObjLo->pData );
fprintf( pFile, "\n" );
}
// write nodes // write nodes
Vec_PtrForEachEntry( vNodes, pObj, i ) Vec_PtrForEachEntry( vNodes, pObj, i )
{ {
......
...@@ -9,6 +9,8 @@ SRC += src/aig/aig/aigCheck.c \ ...@@ -9,6 +9,8 @@ SRC += src/aig/aig/aigCheck.c \
src/aig/aig/aigOrder.c \ src/aig/aig/aigOrder.c \
src/aig/aig/aigPart.c \ src/aig/aig/aigPart.c \
src/aig/aig/aigRepr.c \ src/aig/aig/aigRepr.c \
src/aig/aig/aigRet.c \
src/aig/aig/aigScl.c \
src/aig/aig/aigSeq.c \ src/aig/aig/aigSeq.c \
src/aig/aig/aigTable.c \ src/aig/aig/aigTable.c \
src/aig/aig/aigTiming.c \ src/aig/aig/aigTiming.c \
......
...@@ -77,6 +77,7 @@ struct Fra_Par_t_ ...@@ -77,6 +77,7 @@ struct Fra_Par_t_
int fRewrite; // use rewriting for constraint reduction int fRewrite; // use rewriting for constraint reduction
int fLatchCorr; // computes latch correspondence only int fLatchCorr; // computes latch correspondence only
int fUseImps; // use implications int fUseImps; // use implications
int fWriteImps; // record implications
}; };
// FRAIG equivalence classes // FRAIG equivalence classes
...@@ -148,7 +149,6 @@ struct Fra_Man_t_ ...@@ -148,7 +149,6 @@ struct Fra_Man_t_
// statistics // statistics
int nSimRounds; int nSimRounds;
int nNodesMiter; int nNodesMiter;
int nLitsZero;
int nLitsBeg; int nLitsBeg;
int nLitsEnd; int nLitsEnd;
int nNodesBeg; int nNodesBeg;
...@@ -202,6 +202,10 @@ static inline void Fra_ClassObjSetRepr( Aig_Obj_t * pObj, Aig_Obj_t * pN ...@@ -202,6 +202,10 @@ static inline void Fra_ClassObjSetRepr( Aig_Obj_t * pObj, Aig_Obj_t * pN
static inline Aig_Obj_t * Fra_ObjChild0Fra( Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Fra_ObjFraig(Aig_ObjFanin0(pObj),i), Aig_ObjFaninC0(pObj)) : NULL; } static inline Aig_Obj_t * Fra_ObjChild0Fra( Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Fra_ObjFraig(Aig_ObjFanin0(pObj),i), Aig_ObjFaninC0(pObj)) : NULL; }
static inline Aig_Obj_t * Fra_ObjChild1Fra( Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Fra_ObjFraig(Aig_ObjFanin1(pObj),i), Aig_ObjFaninC1(pObj)) : NULL; } static inline Aig_Obj_t * Fra_ObjChild1Fra( Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Fra_ObjFraig(Aig_ObjFanin1(pObj),i), Aig_ObjFaninC1(pObj)) : NULL; }
static inline int Fra_ImpLeft( int Imp ) { return Imp & 0xFFFF; }
static inline int Fra_ImpRight( int Imp ) { return Imp >> 16; }
static inline int Fra_ImpCreate( int Left, int Right ) { return (Right << 16) | Left; }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// ITERATORS /// /// ITERATORS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -222,7 +226,7 @@ extern void Fra_ClassesCopyReprs( Fra_Cla_t * p, Vec_Ptr_t * vFai ...@@ -222,7 +226,7 @@ extern void Fra_ClassesCopyReprs( Fra_Cla_t * p, Vec_Ptr_t * vFai
extern void Fra_ClassesPrint( Fra_Cla_t * p, int fVeryVerbose ); extern void Fra_ClassesPrint( Fra_Cla_t * p, int fVeryVerbose );
extern void Fra_ClassesPrepare( Fra_Cla_t * p, int fLatchCorr ); extern void Fra_ClassesPrepare( Fra_Cla_t * p, int fLatchCorr );
extern int Fra_ClassesRefine( Fra_Cla_t * p ); extern int Fra_ClassesRefine( Fra_Cla_t * p );
extern int Fra_ClassesRefine1( Fra_Cla_t * p ); extern int Fra_ClassesRefine1( Fra_Cla_t * p, int fRefineNewClass, int * pSkipped );
extern int Fra_ClassesCountLits( Fra_Cla_t * p ); extern int Fra_ClassesCountLits( Fra_Cla_t * p );
extern int Fra_ClassesCountPairs( Fra_Cla_t * p ); extern int Fra_ClassesCountPairs( Fra_Cla_t * p );
extern void Fra_ClassesTest( Fra_Cla_t * p, int Id1, int Id2 ); extern void Fra_ClassesTest( Fra_Cla_t * p, int Id1, int Id2 );
...@@ -233,18 +237,24 @@ extern Aig_Man_t * Fra_ClassesDeriveAig( Fra_Cla_t * p, int nFramesK ); ...@@ -233,18 +237,24 @@ extern Aig_Man_t * Fra_ClassesDeriveAig( Fra_Cla_t * p, int nFramesK );
/*=== fraCnf.c ========================================================*/ /*=== fraCnf.c ========================================================*/
extern void Fra_CnfNodeAddToSolver( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ); extern void Fra_CnfNodeAddToSolver( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
/*=== fraCore.c ========================================================*/ /*=== fraCore.c ========================================================*/
extern Aig_Man_t * Fra_FraigPerform( Aig_Man_t * pManAig, Fra_Par_t * pPars );
extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig );
extern void Fra_FraigSweep( Fra_Man_t * pManAig ); extern void Fra_FraigSweep( Fra_Man_t * pManAig );
extern int Fra_FraigMiterStatus( Aig_Man_t * p ); extern int Fra_FraigMiterStatus( Aig_Man_t * p );
extern Aig_Man_t * Fra_FraigPerform( Aig_Man_t * pManAig, Fra_Par_t * pPars );
extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig );
extern Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax );
/*=== fraImp.c ========================================================*/ /*=== fraImp.c ========================================================*/
extern Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, int fLatchCorr ); extern Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, int fLatchCorr );
extern void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums ); extern void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums );
extern int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, int Pos ); extern int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, int Pos );
extern int Fra_ImpRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vImps ); extern int Fra_ImpRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vImps );
extern void Fra_ImpCompactArray( Vec_Int_t * vImps ); extern void Fra_ImpCompactArray( Vec_Int_t * vImps );
extern double Fra_ImpComputeStateSpaceRatio( Fra_Man_t * p );
extern int Fra_ImpVerifyUsingSimulation( Fra_Man_t * p );
extern void Fra_ImpRecordInManager( Fra_Man_t * p, Aig_Man_t * pNew );
/*=== fraInd.c ========================================================*/ /*=== fraInd.c ========================================================*/
extern Aig_Man_t * Fra_FraigInduction( Aig_Man_t * p, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose, int * pnIter ); extern Aig_Man_t * Fra_FraigInduction( Aig_Man_t * p, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fVerbose, int * pnIter );
/*=== fraLcr.c ========================================================*/
extern Aig_Man_t * Fra_FraigLatchCorrespondence( Aig_Man_t * pAig, int nFramesP, int nConfMax, int fVerbose, int * pnIter );
/*=== fraMan.c ========================================================*/ /*=== fraMan.c ========================================================*/
extern void Fra_ParamsDefault( Fra_Par_t * pParams ); extern void Fra_ParamsDefault( Fra_Par_t * pParams );
extern void Fra_ParamsDefaultSeq( Fra_Par_t * pParams ); extern void Fra_ParamsDefaultSeq( Fra_Par_t * pParams );
...@@ -259,7 +269,7 @@ extern int Fra_NodesAreEquiv( Fra_Man_t * p, Aig_Obj_t * pOld, A ...@@ -259,7 +269,7 @@ extern int Fra_NodesAreEquiv( Fra_Man_t * p, Aig_Obj_t * pOld, A
extern int Fra_NodesAreImp( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew, int fComplL, int fComplR ); extern int Fra_NodesAreImp( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew, int fComplL, int fComplR );
extern int Fra_NodeIsConst( Fra_Man_t * p, Aig_Obj_t * pNew ); extern int Fra_NodeIsConst( Fra_Man_t * p, Aig_Obj_t * pNew );
/*=== fraSec.c ========================================================*/ /*=== fraSec.c ========================================================*/
extern int Fra_FraigSec( Aig_Man_t * p, int nFrames, int fVerbose, int fVeryVerbose ); extern int Fra_FraigSec( Aig_Man_t * p, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose );
/*=== fraSim.c ========================================================*/ /*=== fraSim.c ========================================================*/
extern int Fra_SmlNodeHash( Aig_Obj_t * pObj, int nTableSize ); extern int Fra_SmlNodeHash( Aig_Obj_t * pObj, int nTableSize );
extern int Fra_SmlNodeIsConst( Aig_Obj_t * pObj ); extern int Fra_SmlNodeIsConst( Aig_Obj_t * pObj );
......
...@@ -31,6 +31,8 @@ struct Fra_Bmc_t_ ...@@ -31,6 +31,8 @@ struct Fra_Bmc_t_
int nPref; // the size of the prefix int nPref; // the size of the prefix
int nDepth; // the depth of the frames int nDepth; // the depth of the frames
int nFramesAll; // the total number of timeframes int nFramesAll; // the total number of timeframes
// implications to be filtered
Vec_Int_t * vImps;
// AIG managers // AIG managers
Aig_Man_t * pAig; // the original AIG manager Aig_Man_t * pAig; // the original AIG manager
Aig_Man_t * pAigFrames; // initialized timeframes Aig_Man_t * pAigFrames; // initialized timeframes
...@@ -67,7 +69,6 @@ static inline Aig_Obj_t * Bmc_ObjChild1Frames( Aig_Obj_t * pObj, int i ) { asse ...@@ -67,7 +69,6 @@ static inline Aig_Obj_t * Bmc_ObjChild1Frames( Aig_Obj_t * pObj, int i ) { asse
int Fra_BmcNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) int Fra_BmcNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
{ {
Fra_Man_t * p = pObj0->pData; Fra_Man_t * p = pObj0->pData;
// Aig_Obj_t ** ppNodes = p->pBmc->pObjToFraig;
Aig_Obj_t * pObjFrames0, * pObjFrames1; Aig_Obj_t * pObjFrames0, * pObjFrames1;
Aig_Obj_t * pObjFraig0, * pObjFraig1; Aig_Obj_t * pObjFraig0, * pObjFraig1;
int i; int i;
...@@ -102,6 +103,69 @@ int Fra_BmcNodeIsConst( Aig_Obj_t * pObj ) ...@@ -102,6 +103,69 @@ int Fra_BmcNodeIsConst( Aig_Obj_t * pObj )
return Fra_BmcNodesAreEqual( pObj, Aig_ManConst1(p->pManAig) ); return Fra_BmcNodesAreEqual( pObj, Aig_ManConst1(p->pManAig) );
} }
/**Function*************************************************************
Synopsis [Refines implications using BMC.]
Description [The input is the combinational FRAIG manager,
which is used to FRAIG the timeframes. ]
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_BmcFilterImplications( Fra_Man_t * p, Fra_Bmc_t * pBmc )
{
Aig_Obj_t * pLeft, * pRight;
Aig_Obj_t * pLeftT, * pRightT;
Aig_Obj_t * pLeftF, * pRightF;
int i, f, Imp, Left, Right;
int fComplL, fComplR;
assert( p->nFramesAll == 1 );
assert( p->pManAig == pBmc->pAigFrames );
Vec_IntForEachEntry( pBmc->vImps, Imp, i )
{
if ( Imp == 0 )
continue;
Left = Fra_ImpLeft(Imp);
Right = Fra_ImpRight(Imp);
// get the corresponding nodes
pLeft = Aig_ManObj( pBmc->pAig, Left );
pRight = Aig_ManObj( pBmc->pAig, Right );
// iterate through the timeframes
for ( f = pBmc->nPref; f < pBmc->nFramesAll; f++ )
{
// get timeframes nodes
pLeftT = Bmc_ObjFrames( pLeft, f );
pRightT = Bmc_ObjFrames( pRight, f );
// get the corresponding FRAIG nodes
pLeftF = Fra_ObjFraig( Aig_Regular(pLeftT), 0 );
pRightF = Fra_ObjFraig( Aig_Regular(pRightT), 0 );
// get the complemented attributes
fComplL = pLeft->fPhase ^ Aig_IsComplement(pLeftF) ^ Aig_IsComplement(pLeftT);
fComplR = pRight->fPhase ^ Aig_IsComplement(pRightF) ^ Aig_IsComplement(pRightT);
// check equality
if ( Aig_Regular(pLeftF) == Aig_Regular(pRightF) )
{
if ( fComplL != fComplR )
Vec_IntWriteEntry( pBmc->vImps, i, 0 );
break;
}
// check the implication
// - if true, a clause is added
// - if false, a cex is simulated
// make sure the implication is refined
if ( Fra_NodesAreImp( p, Aig_Regular(pLeftF), Aig_Regular(pRightF), fComplL, fComplR ) != 1 )
{
Vec_IntWriteEntry( pBmc->vImps, i, 0 );
break;
}
}
}
Fra_ImpCompactArray( pBmc->vImps );
}
/**Function************************************************************* /**Function*************************************************************
...@@ -125,8 +189,6 @@ Fra_Bmc_t * Fra_BmcStart( Aig_Man_t * pAig, int nPref, int nDepth ) ...@@ -125,8 +189,6 @@ Fra_Bmc_t * Fra_BmcStart( Aig_Man_t * pAig, int nPref, int nDepth )
p->nFramesAll = nPref + nDepth; p->nFramesAll = nPref + nDepth;
p->pObjToFrames = ALLOC( Aig_Obj_t *, p->nFramesAll * (Aig_ManObjIdMax(pAig) + 1) ); p->pObjToFrames = ALLOC( Aig_Obj_t *, p->nFramesAll * (Aig_ManObjIdMax(pAig) + 1) );
memset( p->pObjToFrames, 0, sizeof(Aig_Obj_t *) * p->nFramesAll * (Aig_ManObjIdMax(pAig) + 1) ); memset( p->pObjToFrames, 0, sizeof(Aig_Obj_t *) * p->nFramesAll * (Aig_ManObjIdMax(pAig) + 1) );
// p->pObjToFraig = ALLOC( Aig_Obj_t *, p->nFramesAll * (Aig_ManObjIdMax(pAig) + 1) );
// memset( p->pObjToFraig, 0, sizeof(Aig_Obj_t *) * p->nFramesAll * (Aig_ManObjIdMax(pAig) + 1) );
return p; return p;
} }
...@@ -215,34 +277,6 @@ Aig_Man_t * Fra_BmcFrames( Fra_Bmc_t * p ) ...@@ -215,34 +277,6 @@ Aig_Man_t * Fra_BmcFrames( Fra_Bmc_t * p )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Constructs FRAIG manager for the initialized timeframes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Fra_BmcFraig( Fra_Bmc_t * p )
{
Aig_Man_t * pFraig;
Fra_Par_t Pars, * pPars = &Pars;
Fra_ParamsDefault( pPars );
pPars->nBTLimitNode = 100000;
pPars->fVerbose = 0;
pPars->fProve = 0;
pPars->fDoSparse = 1;
pPars->fSpeculate = 0;
pPars->fChoicing = 0;
pFraig = Fra_FraigPerform( p->pAigFrames, pPars );
p->pObjToFraig = p->pAigFrames->pObjCopies;
p->pAigFrames->pObjCopies = NULL;
return pFraig;
}
/**Function*************************************************************
Synopsis [Performs BMC for the given AIG.] Synopsis [Performs BMC for the given AIG.]
Description [] Description []
...@@ -255,12 +289,22 @@ Aig_Man_t * Fra_BmcFraig( Fra_Bmc_t * p ) ...@@ -255,12 +289,22 @@ Aig_Man_t * Fra_BmcFraig( Fra_Bmc_t * p )
void Fra_BmcPerform( Fra_Man_t * p, int nPref, int nDepth ) void Fra_BmcPerform( Fra_Man_t * p, int nPref, int nDepth )
{ {
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
int i, clk = clock(); int i, nImpsOld, clk = clock();
assert( p->pBmc == NULL ); assert( p->pBmc == NULL );
// derive and fraig the frames // derive and fraig the frames
p->pBmc = Fra_BmcStart( p->pManAig, nPref, nDepth ); p->pBmc = Fra_BmcStart( p->pManAig, nPref, nDepth );
p->pBmc->pAigFrames = Fra_BmcFrames( p->pBmc ); p->pBmc->pAigFrames = Fra_BmcFrames( p->pBmc );
p->pBmc->pAigFraig = Fra_BmcFraig( p->pBmc ); // if implications are present, configure the AIG manager to check them
if ( p->pCla->vImps )
{
p->pBmc->pAigFrames->pImpFunc = Fra_BmcFilterImplications;
p->pBmc->pAigFrames->pImpData = p->pBmc;
p->pBmc->vImps = p->pCla->vImps;
nImpsOld = Vec_IntSize(p->pCla->vImps);
}
p->pBmc->pAigFraig = Fra_FraigEquivence( p->pBmc->pAigFrames, 1000000 );
p->pBmc->pObjToFraig = p->pBmc->pAigFrames->pObjCopies;
p->pBmc->pAigFrames->pObjCopies = NULL;
// annotate frames nodes with pointers to the manager // annotate frames nodes with pointers to the manager
Aig_ManForEachObj( p->pBmc->pAigFrames, pObj, i ) Aig_ManForEachObj( p->pBmc->pAigFrames, pObj, i )
pObj->pData = p; pObj->pData = p;
...@@ -271,19 +315,31 @@ void Fra_BmcPerform( Fra_Man_t * p, int nPref, int nDepth ) ...@@ -271,19 +315,31 @@ void Fra_BmcPerform( Fra_Man_t * p, int nPref, int nDepth )
Aig_ManNodeNum(p->pBmc->pAig), p->pBmc->nFramesAll, Aig_ManNodeNum(p->pBmc->pAig), p->pBmc->nFramesAll,
Aig_ManNodeNum(p->pBmc->pAigFrames), Aig_ManNodeNum(p->pBmc->pAigFraig) ); Aig_ManNodeNum(p->pBmc->pAigFrames), Aig_ManNodeNum(p->pBmc->pAigFraig) );
PRT( "Time", clock() - clk ); PRT( "Time", clock() - clk );
printf( "Before BMC: " ); Fra_ClassesPrint( p->pCla, 0 ); printf( "Before BMC: " );
// Fra_ClassesPrint( p->pCla, 0 );
printf( "Const = %5d. Class = %5d. Lit = %5d. ",
Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses), Fra_ClassesCountLits(p->pCla) );
if ( p->pCla->vImps && Vec_IntSize(p->pCla->vImps) > 0 )
printf( "Imp = %5d. ", nImpsOld );
printf( "\n" );
} }
// refine the classes // refine the classes
p->pCla->pFuncNodeIsConst = Fra_BmcNodeIsConst; p->pCla->pFuncNodeIsConst = Fra_BmcNodeIsConst;
p->pCla->pFuncNodesAreEqual = Fra_BmcNodesAreEqual; p->pCla->pFuncNodesAreEqual = Fra_BmcNodesAreEqual;
Fra_ClassesRefine( p->pCla ); Fra_ClassesRefine( p->pCla );
Fra_ClassesRefine1( p->pCla ); Fra_ClassesRefine1( p->pCla, 1, NULL );
p->pCla->pFuncNodeIsConst = Fra_SmlNodeIsConst; p->pCla->pFuncNodeIsConst = Fra_SmlNodeIsConst;
p->pCla->pFuncNodesAreEqual = Fra_SmlNodesAreEqual; p->pCla->pFuncNodesAreEqual = Fra_SmlNodesAreEqual;
// report the results // report the results
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
{ {
printf( "After BMC: " ); Fra_ClassesPrint( p->pCla, 0 ); printf( "After BMC: " );
// Fra_ClassesPrint( p->pCla, 0 );
printf( "Const = %5d. Class = %5d. Lit = %5d. ",
Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses), Fra_ClassesCountLits(p->pCla) );
if ( p->pCla->vImps && Vec_IntSize(p->pCla->vImps) > 0 )
printf( "Imp = %5d. ", Vec_IntSize(p->pCla->vImps) );
printf( "\n" );
} }
// free the BMC manager // free the BMC manager
Fra_BmcStop( p->pBmc ); Fra_BmcStop( p->pBmc );
......
...@@ -520,10 +520,10 @@ int Fra_ClassesRefine( Fra_Cla_t * p ) ...@@ -520,10 +520,10 @@ int Fra_ClassesRefine( Fra_Cla_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Fra_ClassesRefine1( Fra_Cla_t * p ) int Fra_ClassesRefine1( Fra_Cla_t * p, int fRefineNewClass, int * pSkipped )
{ {
Aig_Obj_t * pObj, ** ppClass; Aig_Obj_t * pObj, ** ppClass;
int i, k, nRefis; int i, k, nRefis = 1;
// check if there is anything to refine // check if there is anything to refine
if ( Vec_PtrSize(p->vClasses1) == 0 ) if ( Vec_PtrSize(p->vClasses1) == 0 )
return 0; return 0;
...@@ -565,7 +565,10 @@ int Fra_ClassesRefine1( Fra_Cla_t * p ) ...@@ -565,7 +565,10 @@ int Fra_ClassesRefine1( Fra_Cla_t * p )
assert( ppClass[0] != NULL ); assert( ppClass[0] != NULL );
Vec_PtrPush( p->vClasses, ppClass ); Vec_PtrPush( p->vClasses, ppClass );
// iteratively refine this class // iteratively refine this class
nRefis = 1 + Fra_RefineClassLastIter( p, p->vClasses ); if ( fRefineNewClass )
nRefis += Fra_RefineClassLastIter( p, p->vClasses );
else if ( pSkipped )
(*pSkipped)++;
return nRefis; return nRefis;
} }
......
...@@ -246,7 +246,7 @@ static inline void Fra_FraigNode( Fra_Man_t * p, Aig_Obj_t * pObj ) ...@@ -246,7 +246,7 @@ static inline void Fra_FraigNode( Fra_Man_t * p, Aig_Obj_t * pObj )
Vec_PtrPush( p->vTimeouts, pObj ); Vec_PtrPush( p->vTimeouts, pObj );
// verify that the counter-example satisfies all the constraints // verify that the counter-example satisfies all the constraints
// if ( p->vCex ) // if ( p->vCex )
// Fra_FraigVerifyCounterEx( p, p->vCex ); // Fra_FraigVerifyCounterEx( p, p->vCex );
// simulate the counter-example and return the Fraig node // simulate the counter-example and return the Fraig node
Fra_SmlResimulate( p ); Fra_SmlResimulate( p );
if ( !p->pPars->nFramesK && Fra_ClassObjRepr(pObj) == pObjRepr ) if ( !p->pPars->nFramesK && Fra_ClassObjRepr(pObj) == pObjRepr )
...@@ -334,12 +334,15 @@ clk = clock(); ...@@ -334,12 +334,15 @@ clk = clock();
if ( p->pPars->fChoicing ) if ( p->pPars->fChoicing )
Aig_ManReprStart( p->pManFraig, Aig_ManObjIdMax(p->pManAig)+1 ); Aig_ManReprStart( p->pManFraig, Aig_ManObjIdMax(p->pManAig)+1 );
// collect initial states // collect initial states
p->nLitsZero = Vec_PtrSize( p->pCla->vClasses1 );
p->nLitsBeg = Fra_ClassesCountLits( p->pCla ); p->nLitsBeg = Fra_ClassesCountLits( p->pCla );
p->nNodesBeg = Aig_ManNodeNum(pManAig); p->nNodesBeg = Aig_ManNodeNum(pManAig);
p->nRegsBeg = Aig_ManRegNum(pManAig); p->nRegsBeg = Aig_ManRegNum(pManAig);
// perform fraig sweep // perform fraig sweep
Fra_FraigSweep( p ); Fra_FraigSweep( p );
// call back the procedure to check implications
if ( pManAig->pImpFunc )
pManAig->pImpFunc( p, pManAig->pImpData );
// finalize the fraiged manager
Fra_ManFinalizeComb( p ); Fra_ManFinalizeComb( p );
if ( p->pPars->fChoicing ) if ( p->pPars->fChoicing )
{ {
...@@ -397,6 +400,32 @@ Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig ) ...@@ -397,6 +400,32 @@ Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig )
pPars->fChoicing = 1; pPars->fChoicing = 1;
return Fra_FraigPerform( pManAig, pPars ); return Fra_FraigPerform( pManAig, pPars );
} }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Fra_FraigEquivence( Aig_Man_t * pManAig, int nConfMax )
{
Aig_Man_t * pFraig;
Fra_Par_t Pars, * pPars = &Pars;
Fra_ParamsDefault( pPars );
pPars->nBTLimitNode = nConfMax;
pPars->fVerbose = 0;
pPars->fProve = 0;
pPars->fDoSparse = 1;
pPars->fSpeculate = 0;
pPars->fChoicing = 0;
pFraig = Fra_FraigPerform( pManAig, pPars );
return pFraig;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
......
...@@ -24,10 +24,6 @@ ...@@ -24,10 +24,6 @@
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
static inline int Sml_ImpLeft( int Imp ) { return Imp & 0xFFFF; }
static inline int Sml_ImpRight( int Imp ) { return Imp >> 16; }
static inline int Sml_ImpCreate( int Left, int Right ) { return (Right << 16) | Left; }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS /// /// FUNCTION DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -43,19 +39,35 @@ static inline int Sml_ImpCreate( int Left, int Right ) { return (Right << 16) ...@@ -43,19 +39,35 @@ static inline int Sml_ImpCreate( int Left, int Right ) { return (Right << 16)
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
static inline int Fra_SmlCountOnesOne( Fra_Sml_t * p, int Node )
{
unsigned * pSim;
int k, Counter = 0;
pSim = Fra_ObjSim( p, Node );
for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
Counter += Aig_WordCountOnes( pSim[k] );
return Counter;
}
/**Function*************************************************************
Synopsis [Counts the number of 1s in each siminfo of each node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int * Fra_SmlCountOnes( Fra_Sml_t * p ) static inline int * Fra_SmlCountOnes( Fra_Sml_t * p )
{ {
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
unsigned * pSim; int i, * pnBits;
int i, k, * pnBits;
pnBits = ALLOC( int, Aig_ManObjIdMax(p->pAig) + 1 ); pnBits = ALLOC( int, Aig_ManObjIdMax(p->pAig) + 1 );
memset( pnBits, 0, sizeof(int) * (Aig_ManObjIdMax(p->pAig) + 1) ); memset( pnBits, 0, sizeof(int) * (Aig_ManObjIdMax(p->pAig) + 1) );
Aig_ManForEachObj( p->pAig, pObj, i ) Aig_ManForEachObj( p->pAig, pObj, i )
{ pnBits[i] = Fra_SmlCountOnesOne( p, i );
pSim = Fra_ObjSim( p, i );
for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
pnBits[i] += Aig_WordCountOnes( pSim[k] );
}
return pnBits; return pnBits;
} }
...@@ -106,6 +118,27 @@ static inline int Sml_NodeNotImpWeight( Fra_Sml_t * p, int Left, int Right ) ...@@ -106,6 +118,27 @@ static inline int Sml_NodeNotImpWeight( Fra_Sml_t * p, int Left, int Right )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Counts the number of 1s in the reverse implication.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Sml_NodeSaveNotImpPatterns( Fra_Sml_t * p, int Left, int Right, unsigned * pResult )
{
unsigned * pSimL, * pSimR;
int k;
pSimL = Fra_ObjSim( p, Left );
pSimR = Fra_ObjSim( p, Right );
for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
pResult[k] |= pSimL[k] & ~pSimR[k];
}
/**Function*************************************************************
Synopsis [Returns the array of nodes sorted by the number of 1s.] Synopsis [Returns the array of nodes sorted by the number of 1s.]
Description [] Description []
...@@ -284,7 +317,6 @@ int Sml_CompareMaxId( unsigned short * pImp1, unsigned short * pImp2 ) ...@@ -284,7 +317,6 @@ int Sml_CompareMaxId( unsigned short * pImp1, unsigned short * pImp2 )
***********************************************************************/ ***********************************************************************/
Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, int fLatchCorr ) Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, int fLatchCorr )
{ {
// Aig_Obj_t * pObj;
int nSimWords = 64; int nSimWords = 64;
Fra_Sml_t * pSeq, * pComb; Fra_Sml_t * pSeq, * pComb;
Vec_Int_t * vImps, * vTemp; Vec_Int_t * vImps, * vTemp;
...@@ -293,21 +325,13 @@ Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, in ...@@ -293,21 +325,13 @@ Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, in
int nImpsTotal = 0, nImpsTried = 0, nImpsNonSeq = 0, nImpsComb = 0, nImpsCollected = 0; int nImpsTotal = 0, nImpsTried = 0, nImpsNonSeq = 0, nImpsComb = 0, nImpsCollected = 0;
int CostMin = AIG_INFINITY, CostMax = 0; int CostMin = AIG_INFINITY, CostMax = 0;
int i, k, Imp, CostRange, clk = clock(); int i, k, Imp, CostRange, clk = clock();
assert( Aig_ManObjIdMax(p->pManAig) + 1 < (1 << 15) );
assert( nImpMaxLimit > 0 && nImpUseLimit > 0 && nImpUseLimit <= nImpMaxLimit ); assert( nImpMaxLimit > 0 && nImpUseLimit > 0 && nImpUseLimit <= nImpMaxLimit );
// normalize both managers // normalize both managers
pComb = Fra_SmlSimulateComb( p->pManAig, nSimWords ); pComb = Fra_SmlSimulateComb( p->pManAig, nSimWords );
pSeq = Fra_SmlSimulateSeq( p->pManAig, p->pPars->nFramesP, nSimWords, 1 ); pSeq = Fra_SmlSimulateSeq( p->pManAig, p->pPars->nFramesP, nSimWords, 1 );
// get the nodes sorted by the number of 1s // get the nodes sorted by the number of 1s
vNodes = Fra_SmlSortUsingOnes( pSeq, fLatchCorr ); vNodes = Fra_SmlSortUsingOnes( pSeq, fLatchCorr );
/*
Aig_ManForEachObj( p->pManAig, pObj, i )
{
printf( "%6s", Aig_ObjIsPi(pObj)? "pi" : (Aig_ObjIsNode(pObj)? "node" : "other" ) );
printf( "%d (%d) :\n", i, pObj->fPhase );
Extra_PrintBinary( stdout, Fra_ObjSim( pComb, i ), 64 ); printf( "\n" );
Extra_PrintBinary( stdout, Fra_ObjSim( pSeq, i ), 64 ); printf( "\n" );
}
*/
// count the total number of implications // count the total number of implications
for ( k = nSimWords * 32; k > 0; k-- ) for ( k = nSimWords * 32; k > 0; k-- )
for ( i = k - 1; i > 0; i-- ) for ( i = k - 1; i > 0; i-- )
...@@ -335,10 +359,8 @@ Aig_ManForEachObj( p->pManAig, pObj, i ) ...@@ -335,10 +359,8 @@ Aig_ManForEachObj( p->pManAig, pObj, i )
nImpsComb++; nImpsComb++;
continue; continue;
} }
// printf( "d=%d c=%d ", k-i, Sml_NodeNotImpWeight(pComb, *pNodesI, *pNodesK) );
nImpsCollected++; nImpsCollected++;
Imp = Sml_ImpCreate( *pNodesI, *pNodesK ); Imp = Fra_ImpCreate( *pNodesI, *pNodesK );
pImpCosts[ Vec_IntSize(vImps) ] = Sml_NodeNotImpWeight(pComb, *pNodesI, *pNodesK); pImpCosts[ Vec_IntSize(vImps) ] = Sml_NodeNotImpWeight(pComb, *pNodesI, *pNodesK);
CostMin = AIG_MIN( CostMin, pImpCosts[ Vec_IntSize(vImps) ] ); CostMin = AIG_MIN( CostMin, pImpCosts[ Vec_IntSize(vImps) ] );
CostMax = AIG_MAX( CostMax, pImpCosts[ Vec_IntSize(vImps) ] ); CostMax = AIG_MAX( CostMax, pImpCosts[ Vec_IntSize(vImps) ] );
...@@ -368,13 +390,16 @@ finish: ...@@ -368,13 +390,16 @@ finish:
(int (*)(const void *, const void *)) Sml_CompareMaxId ); (int (*)(const void *, const void *)) Sml_CompareMaxId );
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
{ {
printf( "Tot = %d. Try = %d. NonS = %d. C = %d. Found = %d. Cost = [%d < %d < %d] ", printf( "Implications: All = %d. Try = %d. NonSeq = %d. Comb = %d. Res = %d.\n",
nImpsTotal, nImpsTried, nImpsNonSeq, nImpsComb, nImpsCollected, CostMin, CostRange, CostMax ); nImpsTotal, nImpsTried, nImpsNonSeq, nImpsComb, nImpsCollected );
printf( "Implication weight: Min = %d. Pivot = %d. Max = %d. ",
CostMin, CostRange, CostMax );
PRT( "Time", clock() - clk ); PRT( "Time", clock() - clk );
} }
return vImps; return vImps;
} }
// the following three procedures are called to // the following three procedures are called to
// - add implications to the SAT solver // - add implications to the SAT solver
// - check implications using the SAT solver // - check implications using the SAT solver
...@@ -401,8 +426,8 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums ) ...@@ -401,8 +426,8 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums )
Vec_IntForEachEntry( vImps, Imp, i ) Vec_IntForEachEntry( vImps, Imp, i )
{ {
// get the corresponding nodes // get the corresponding nodes
pLeft = Aig_ManObj( p->pManAig, Sml_ImpLeft(Imp) ); pLeft = Aig_ManObj( p->pManAig, Fra_ImpLeft(Imp) );
pRight = Aig_ManObj( p->pManAig, Sml_ImpRight(Imp) ); pRight = Aig_ManObj( p->pManAig, Fra_ImpRight(Imp) );
// check if all the nodes are present // check if all the nodes are present
for ( f = 0; f < p->pPars->nFramesK; f++ ) for ( f = 0; f < p->pPars->nFramesK; f++ )
{ {
...@@ -431,7 +456,7 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums ) ...@@ -431,7 +456,7 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums )
// get the complemented attributes // get the complemented attributes
fComplL = pLeft->fPhase ^ Aig_IsComplement(pLeftF); fComplL = pLeft->fPhase ^ Aig_IsComplement(pLeftF);
fComplR = pRight->fPhase ^ Aig_IsComplement(pRightF); fComplR = pRight->fPhase ^ Aig_IsComplement(pRightF);
// get the constaint // get the constraint
// L => R L' v R (complement = L & R') // L => R L' v R (complement = L & R')
pLits[0] = 2 * Left + !fComplL; pLits[0] = 2 * Left + !fComplL;
pLits[1] = 2 * Right + fComplR; pLits[1] = 2 * Right + fComplR;
...@@ -476,8 +501,8 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in ...@@ -476,8 +501,8 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in
{ {
if ( Imp == 0 ) if ( Imp == 0 )
continue; continue;
Left = Sml_ImpLeft(Imp); Left = Fra_ImpLeft(Imp);
Right = Sml_ImpRight(Imp); Right = Fra_ImpRight(Imp);
Max = AIG_MAX( Left, Right ); Max = AIG_MAX( Left, Right );
assert( Max >= pNode->Id ); assert( Max >= pNode->Id );
if ( Max > pNode->Id ) if ( Max > pNode->Id )
...@@ -494,9 +519,6 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in ...@@ -494,9 +519,6 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in
// check equality // check equality
if ( Aig_Regular(pLeftF) == Aig_Regular(pRightF) ) if ( Aig_Regular(pLeftF) == Aig_Regular(pRightF) )
{ {
// assert( fComplL == fComplR );
// if ( fComplL != fComplR )
// printf( "Fra_ImpCheckForNode(): Unexpected situation!\n" );
if ( fComplL != fComplR ) if ( fComplL != fComplR )
Vec_IntWriteEntry( vImps, i, 0 ); Vec_IntWriteEntry( vImps, i, 0 );
continue; continue;
...@@ -507,6 +529,7 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in ...@@ -507,6 +529,7 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in
// make sure the implication is refined // make sure the implication is refined
if ( Fra_NodesAreImp( p, Aig_Regular(pLeftF), Aig_Regular(pRightF), fComplL, fComplR ) == 0 ) if ( Fra_NodesAreImp( p, Aig_Regular(pLeftF), Aig_Regular(pRightF), fComplL, fComplR ) == 0 )
{ {
p->pCla->fRefinement = 1;
Fra_SmlResimulate( p ); Fra_SmlResimulate( p );
if ( Vec_IntEntry(vImps, i) != 0 ) if ( Vec_IntEntry(vImps, i) != 0 )
printf( "Fra_ImpCheckForNode(): Implication is not refined!\n" ); printf( "Fra_ImpCheckForNode(): Implication is not refined!\n" );
...@@ -536,8 +559,8 @@ int Fra_ImpRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vImps ) ...@@ -536,8 +559,8 @@ int Fra_ImpRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vImps )
if ( Imp == 0 ) if ( Imp == 0 )
continue; continue;
// get the corresponding nodes // get the corresponding nodes
pLeft = Aig_ManObj( p->pManAig, Sml_ImpLeft(Imp) ); pLeft = Aig_ManObj( p->pManAig, Fra_ImpLeft(Imp) );
pRight = Aig_ManObj( p->pManAig, Sml_ImpRight(Imp) ); pRight = Aig_ManObj( p->pManAig, Fra_ImpRight(Imp) );
// check if implication holds using this simulation info // check if implication holds using this simulation info
if ( !Sml_NodeCheckImp(p->pSml, pLeft->Id, pRight->Id) ) if ( !Sml_NodeCheckImp(p->pSml, pLeft->Id, pRight->Id) )
{ {
...@@ -569,6 +592,113 @@ void Fra_ImpCompactArray( Vec_Int_t * vImps ) ...@@ -569,6 +592,113 @@ void Fra_ImpCompactArray( Vec_Int_t * vImps )
Vec_IntShrink( vImps, k ); Vec_IntShrink( vImps, k );
} }
/**Function*************************************************************
Synopsis [Determines the ratio of the state space by computed implications.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
double Fra_ImpComputeStateSpaceRatio( Fra_Man_t * p )
{
int nSimWords = 64;
Fra_Sml_t * pComb;
unsigned * pResult;
double Ratio = 0.0;
int Left, Right, Imp, i;
if ( p->pCla->vImps == NULL || Vec_IntSize(p->pCla->vImps) == 0 )
return Ratio;
// simulate the AIG manager with combinational patterns
pComb = Fra_SmlSimulateComb( p->pManAig, nSimWords );
// go through the implications and collect where they do not hold
pResult = Fra_ObjSim( pComb, 0 );
assert( pResult[0] == 0 );
Vec_IntForEachEntry( p->pCla->vImps, Imp, i )
{
Left = Fra_ImpLeft(Imp);
Right = Fra_ImpRight(Imp);
Sml_NodeSaveNotImpPatterns( pComb, Left, Right, pResult );
}
// count the number of ones in this area
Ratio = 100.0 * Fra_SmlCountOnesOne( pComb, 0 ) / (32*(pComb->nWordsTotal-pComb->nWordsPref));
Fra_SmlStop( pComb );
return Ratio;
}
/**Function*************************************************************
Synopsis [Returns the number of failed implications.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fra_ImpVerifyUsingSimulation( Fra_Man_t * p )
{
int nSimWords = 2000;
Fra_Sml_t * pSeq;
char * pfFails;
int Left, Right, Imp, i, Counter;
if ( p->pCla->vImps == NULL || Vec_IntSize(p->pCla->vImps) == 0 )
return 0;
// simulate the AIG manager with combinational patterns
pSeq = Fra_SmlSimulateSeq( p->pManAig, p->pPars->nFramesP, nSimWords, 4 );
// go through the implications and check how many of them do not hold
pfFails = ALLOC( char, Vec_IntSize(p->pCla->vImps) );
memset( pfFails, 0, sizeof(char) * Vec_IntSize(p->pCla->vImps) );
Vec_IntForEachEntry( p->pCla->vImps, Imp, i )
{
Left = Fra_ImpLeft(Imp);
Right = Fra_ImpRight(Imp);
pfFails[i] = !Sml_NodeCheckImp( pSeq, Left, Right );
}
// count how many has failed
Counter = 0;
for ( i = 0; i < Vec_IntSize(p->pCla->vImps); i++ )
Counter += pfFails[i];
free( pfFails );
return Counter;
}
/**Function*************************************************************
Synopsis [Record proven implications in the AIG manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_ImpRecordInManager( Fra_Man_t * p, Aig_Man_t * pNew )
{
Aig_Obj_t * pLeft, * pRight, * pMiter;
int nPosOld, Imp, i;
if ( p->pCla->vImps == NULL || Vec_IntSize(p->pCla->vImps) == 0 )
return;
// go through the implication
nPosOld = Aig_ManPoNum(pNew);
Vec_IntForEachEntry( p->pCla->vImps, Imp, i )
{
pLeft = Aig_ManObj( p->pManAig, Fra_ImpLeft(Imp) );
pRight = Aig_ManObj( p->pManAig, Fra_ImpRight(Imp) );
// record the implication: L' + R
pMiter = Aig_Or( pNew,
Aig_NotCond(pLeft->pData, !pLeft->fPhase),
Aig_NotCond(pRight->pData, pRight->fPhase) );
Aig_ObjCreatePo( pNew, pMiter );
}
pNew->nAsserts = Aig_ManPoNum(pNew) - nPosOld;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -177,6 +177,61 @@ Aig_Man_t * Fra_FramesWithClasses( Fra_Man_t * p ) ...@@ -177,6 +177,61 @@ Aig_Man_t * Fra_FramesWithClasses( Fra_Man_t * p )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Prepares the inductive case with speculative reduction.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_FramesAddMore( Aig_Man_t * p, int nFrames )
{
Aig_Obj_t * pObj, ** pLatches;
int i, k, f, nNodesOld;
// set copy pointer of each object to point to itself
Aig_ManForEachObj( p, pObj, i )
pObj->pData = pObj;
// iterate and add objects
nNodesOld = Aig_ManObjIdMax(p);
pLatches = ALLOC( Aig_Obj_t *, Aig_ManRegNum(p) );
for ( f = 0; f < nFrames; f++ )
{
// clean latch inputs and outputs
Aig_ManForEachLiSeq( p, pObj, i )
pObj->pData = NULL;
Aig_ManForEachLoSeq( p, pObj, i )
pObj->pData = NULL;
// save the latch input values
k = 0;
Aig_ManForEachLiSeq( p, pObj, i )
{
if ( Aig_ObjFanin0(pObj)->pData )
pLatches[k++] = Aig_ObjChild0Copy(pObj);
else
pLatches[k++] = NULL;
}
// insert them as the latch output values
k = 0;
Aig_ManForEachLoSeq( p, pObj, i )
pObj->pData = pLatches[k++];
// create the next time frame of nodes
Aig_ManForEachNode( p, pObj, i )
{
if ( i > nNodesOld )
break;
if ( Aig_ObjFanin0(pObj)->pData && Aig_ObjFanin1(pObj)->pData )
pObj->pData = Aig_And( p, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
else
pObj->pData = NULL;
}
}
free( pLatches );
}
/**Function*************************************************************
Synopsis [Performs choicing of the AIG.] Synopsis [Performs choicing of the AIG.]
Description [] Description []
...@@ -186,7 +241,7 @@ Aig_Man_t * Fra_FramesWithClasses( Fra_Man_t * p ) ...@@ -186,7 +241,7 @@ Aig_Man_t * Fra_FramesWithClasses( Fra_Man_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose, int * pnIter ) Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fVerbose, int * pnIter )
{ {
int fUseSimpleCnf = 0; int fUseSimpleCnf = 0;
int fUseOldSimulation = 0; int fUseOldSimulation = 0;
...@@ -201,8 +256,9 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK, ...@@ -201,8 +256,9 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK,
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
Cnf_Dat_t * pCnf; Cnf_Dat_t * pCnf;
Aig_Man_t * pManAigNew; Aig_Man_t * pManAigNew;
// Vec_Int_t * vImps; int nNodesBeg, nRegsBeg, Temp;
int nIter, i, clk = clock(), clk2; int nIter, i, clk = clock(), clk2;
if ( Aig_ManNodeNum(pManAig) == 0 ) if ( Aig_ManNodeNum(pManAig) == 0 )
{ {
if ( pnIter ) *pnIter = 0; if ( pnIter ) *pnIter = 0;
...@@ -212,6 +268,12 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK, ...@@ -212,6 +268,12 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK,
assert( Aig_ManRegNum(pManAig) > 0 ); assert( Aig_ManRegNum(pManAig) > 0 );
assert( nFramesK > 0 ); assert( nFramesK > 0 );
//Aig_ManShow( pManAig, 0, NULL ); //Aig_ManShow( pManAig, 0, NULL );
nNodesBeg = Aig_ManNodeNum(pManAig);
nRegsBeg = Aig_ManRegNum(pManAig);
// enhance the AIG by adding timeframes
// Fra_FramesAddMore( pManAig, 3 );
// get parameters // get parameters
Fra_ParamsDefaultSeq( pPars ); Fra_ParamsDefaultSeq( pPars );
...@@ -222,6 +284,7 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK, ...@@ -222,6 +284,7 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesP, int nFramesK,
pPars->fRewrite = fRewrite; pPars->fRewrite = fRewrite;
pPars->fLatchCorr = fLatchCorr; pPars->fLatchCorr = fLatchCorr;
pPars->fUseImps = fUseImps; pPars->fUseImps = fUseImps;
pPars->fWriteImps = fWriteImps;
// start the fraig manager for this run // start the fraig manager for this run
p = Fra_ManStart( pManAig, pPars ); p = Fra_ManStart( pManAig, pPars );
...@@ -255,19 +318,19 @@ PRT( "Time", clock() - clk ); ...@@ -255,19 +318,19 @@ PRT( "Time", clock() - clk );
p->pSml = Fra_SmlStart( pManAig, 0, pPars->nFramesK + 1, pPars->nSimWords ); p->pSml = Fra_SmlStart( pManAig, 0, pPars->nFramesK + 1, pPars->nSimWords );
} }
// perform BMC (for the min number of frames)
Fra_BmcPerform( p, pPars->nFramesP, pPars->nFramesK );
//Fra_ClassesPrint( p->pCla, 1 );
// p->vCex = Vec_IntAlloc( 1000 );
// select the most expressive implications // select the most expressive implications
if ( pPars->fUseImps ) if ( pPars->fUseImps )
p->pCla->vImps = Fra_ImpDerive( p, 5000000, pPars->nMaxImps, pPars->fLatchCorr ); p->pCla->vImps = Fra_ImpDerive( p, 5000000, pPars->nMaxImps, pPars->fLatchCorr );
p->nLitsZero = Vec_PtrSize( p->pCla->vClasses1 ); // perform BMC (for the min number of frames)
Fra_BmcPerform( p, pPars->nFramesP, pPars->nFramesK+1 ); // +1 is needed to prevent non-refinement
//Fra_ClassesPrint( p->pCla, 1 );
// if ( p->vCex == NULL )
// p->vCex = Vec_IntAlloc( 1000 );
p->nLitsBeg = Fra_ClassesCountLits( p->pCla ); p->nLitsBeg = Fra_ClassesCountLits( p->pCla );
p->nNodesBeg = Aig_ManNodeNum(pManAig); p->nNodesBeg = nNodesBeg; // Aig_ManNodeNum(pManAig);
p->nRegsBeg = Aig_ManRegNum(pManAig); p->nRegsBeg = nRegsBeg; // Aig_ManRegNum(pManAig);
// dump AIG of the timeframes // dump AIG of the timeframes
// pManAigNew = Fra_ClassesDeriveAig( p->pCla, pPars->nFramesK ); // pManAigNew = Fra_ClassesDeriveAig( p->pCla, pPars->nFramesK );
...@@ -279,6 +342,8 @@ PRT( "Time", clock() - clk ); ...@@ -279,6 +342,8 @@ PRT( "Time", clock() - clk );
p->pCla->fRefinement = 1; p->pCla->fRefinement = 1;
for ( nIter = 0; p->pCla->fRefinement; nIter++ ) for ( nIter = 0; p->pCla->fRefinement; nIter++ )
{ {
int nLitsOld = Fra_ClassesCountLits(p->pCla);
int nImpsOld = p->pCla->vImps? Vec_IntSize(p->pCla->vImps) : 0;
// mark the classes as non-refined // mark the classes as non-refined
p->pCla->fRefinement = 0; p->pCla->fRefinement = 0;
// derive non-init K-timeframes while implementing e-classes // derive non-init K-timeframes while implementing e-classes
...@@ -325,13 +390,13 @@ PRT( "Time", clock() - clk ); ...@@ -325,13 +390,13 @@ PRT( "Time", clock() - clk );
// report the intermediate results // report the intermediate results
if ( fVerbose ) if ( fVerbose )
{ {
printf( "%3d : Const = %6d. Class = %6d. L = %6d. LR = %6d. %s = %6d. NR = %6d.\n", printf( "%3d : Const = %6d. Class = %6d. L = %6d. LR = %6d. ",
nIter, Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses), nIter, Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses),
Fra_ClassesCountLits(p->pCla), p->pManFraig->nAsserts, Fra_ClassesCountLits(p->pCla), p->pManFraig->nAsserts );
p->pCla->vImps? "I" : "N", if ( p->pCla->vImps )
p->pCla->vImps? Vec_IntSize(p->pCla->vImps) : Aig_ManNodeNum(p->pManAig), printf( "I = %6d. ", Vec_IntSize(p->pCla->vImps) );
Aig_ManNodeNum(p->pManFraig) ); printf( "NR = %6d.\n", Aig_ManNodeNum(p->pManFraig) );
} }
// perform sweeping // perform sweeping
p->nSatCallsRecent = 0; p->nSatCallsRecent = 0;
...@@ -341,18 +406,40 @@ PRT( "Time", clock() - clk ); ...@@ -341,18 +406,40 @@ PRT( "Time", clock() - clk );
assert( p->vTimeouts == NULL ); assert( p->vTimeouts == NULL );
if ( p->vTimeouts ) if ( p->vTimeouts )
printf( "Fra_FraigInduction(): SAT solver timed out!\n" ); printf( "Fra_FraigInduction(): SAT solver timed out!\n" );
// cleanup // cleanup
Fra_ManClean( p ); Fra_ManClean( p );
// if ( nIter == 3 ) // check if refinement has happened
// break; // p->pCla->fRefinement = (int)(nLitsOld != Fra_ClassesCountLits(p->pCla));
if ( p->pCla->fRefinement &&
nLitsOld == Fra_ClassesCountLits(p->pCla) &&
nImpsOld == (p->pCla->vImps? Vec_IntSize(p->pCla->vImps) : 0) )
{
printf( "Fra_FraigInduction(): Internal error. The result may not verify.\n" );
break;
}
} }
// Fra_ClassesPrint( p->pCla, 1 ); // check implications using simulation
// Fra_ClassesSelectRepr( p->pCla ); if ( p->pCla->vImps && Vec_IntSize(p->pCla->vImps) )
{
int clk = clock();
if ( Temp = Fra_ImpVerifyUsingSimulation( p ) )
printf( "Implications failing the simulation test = %d (out of %d). ", Temp, Vec_IntSize(p->pCla->vImps) );
else
printf( "All %d implications have passed the simulation test. ", Vec_IntSize(p->pCla->vImps) );
PRT( "Time", clock() - clk );
}
// move the classes into representatives and reduce AIG // move the classes into representatives and reduce AIG
clk2 = clock(); clk2 = clock();
// Fra_ClassesPrint( p->pCla, 1 );
Fra_ClassesSelectRepr( p->pCla );
Fra_ClassesCopyReprs( p->pCla, p->vTimeouts ); Fra_ClassesCopyReprs( p->pCla, p->vTimeouts );
pManAigNew = Aig_ManDupRepr( pManAig ); pManAigNew = Aig_ManDupRepr( pManAig );
// add implications to the manager
if ( fWriteImps && p->pCla->vImps && Vec_IntSize(p->pCla->vImps) )
Fra_ImpRecordInManager( p, pManAigNew );
// cleanup the new manager
Aig_ManSeqCleanup( pManAigNew ); Aig_ManSeqCleanup( pManAigNew );
// Aig_ManCountMergeRegs( pManAigNew ); // Aig_ManCountMergeRegs( pManAigNew );
p->timeTrav += clock() - clk2; p->timeTrav += clock() - clk2;
......
/**CFile****************************************************************
FileName [fraLcorr.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [New FRAIG package.]
Synopsis [Latch correspondence computation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 30, 2007.]
Revision [$Id: fraLcorr.c,v 1.00 2007/06/30 00:00:00 alanmi Exp $]
***********************************************************************/
#include "fra.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
typedef struct Fra_Lcr_t_ Fra_Lcr_t;
struct Fra_Lcr_t_
{
// original AIG
Aig_Man_t * pAig;
// equivalence class representation
Fra_Cla_t * pCla;
// partitioning information
Vec_Ptr_t * vParts; // output partitions
int * pInToOutPart; // mapping of PI num into PO partition num
int * pInToOutNum; // mapping of PI num into the num of this PO in the partition
// AIGs for the partitions
Vec_Ptr_t * vFraigs;
// other variables
int fRefining;
// parameters
int nFramesP;
int fVerbose;
// statistics
int nIters;
int nLitsBeg;
int nLitsEnd;
int nNodesBeg;
int nNodesEnd;
int nRegsBeg;
int nRegsEnd;
// runtime
int timeSim;
int timePart;
int timeTrav;
int timeFraig;
int timeUpdate;
int timeTotal;
};
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Allocates the retiming manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Fra_Lcr_t * Lcr_ManAlloc( Aig_Man_t * pAig )
{
Fra_Lcr_t * p;
p = ALLOC( Fra_Lcr_t, 1 );
memset( p, 0, sizeof(Fra_Lcr_t) );
p->pAig = pAig;
p->pInToOutPart = ALLOC( int, Aig_ManPiNum(pAig) );
memset( p->pInToOutPart, 0, sizeof(int) * Aig_ManPiNum(pAig) );
p->pInToOutNum = ALLOC( int, Aig_ManPiNum(pAig) );
memset( p->pInToOutNum, 0, sizeof(int) * Aig_ManPiNum(pAig) );
p->vFraigs = Vec_PtrAlloc( 1000 );
return p;
}
/**Function*************************************************************
Synopsis [Prints stats for the fraiging manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Lcr_ManPrint( Fra_Lcr_t * p )
{
printf( "Iterations = %d. LitBeg = %d. LitEnd = %d. (%6.2f %%).\n",
p->nIters, p->nLitsBeg, p->nLitsEnd, 100.0*p->nLitsEnd/p->nLitsBeg );
printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/p->nNodesBeg,
p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/p->nRegsBeg );
PRT( "AIG simulation ", p->timeSim );
PRT( "AIG partitioning", p->timePart );
PRT( "AIG rebuiding ", p->timeTrav );
PRT( "FRAIGing ", p->timeFraig );
PRT( "AIG updating ", p->timeUpdate );
PRT( "TOTAL RUNTIME ", p->timeTotal );
}
/**Function*************************************************************
Synopsis [Deallocates the retiming manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Lcr_ManFree( Fra_Lcr_t * p )
{
Aig_Obj_t * pObj;
int i;
if ( p->fVerbose )
Lcr_ManPrint( p );
Aig_ManForEachPi( p->pAig, pObj, i )
pObj->pNext = NULL;
Vec_PtrFree( p->vFraigs );
if ( p->pCla ) Fra_ClassesStop( p->pCla );
if ( p->vParts ) Vec_VecFree( (Vec_Vec_t *)p->vParts );
free( p->pInToOutPart );
free( p->pInToOutNum );
free( p );
}
/**Function*************************************************************
Synopsis [Prepare the AIG for class computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Fra_Man_t * Fra_LcrAigPrepare( Aig_Man_t * pAig )
{
Fra_Man_t * p;
Aig_Obj_t * pObj;
int i;
p = ALLOC( Fra_Man_t, 1 );
memset( p, 0, sizeof(Fra_Man_t) );
Aig_ManForEachPi( pAig, pObj, i )
pObj->pData = p;
return p;
}
/**Function*************************************************************
Synopsis [Prepare the AIG for class computation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_LcrAigPrepareTwo( Aig_Man_t * pAig, Fra_Man_t * p )
{
Aig_Obj_t * pObj;
int i;
Aig_ManForEachPi( pAig, pObj, i )
pObj->pData = p;
}
/**Function*************************************************************
Synopsis [Compares two nodes for equivalence after partitioned fraiging.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fra_LcrNodesAreEqual( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
{
Fra_Man_t * pTemp = pObj0->pData;
Fra_Lcr_t * pLcr = (Fra_Lcr_t *)pTemp->pBmc;
Aig_Man_t * pFraig;
Aig_Obj_t * pOut0, * pOut1;
int nPart0, nPart1;
assert( Aig_ObjIsPi(pObj0) );
assert( Aig_ObjIsPi(pObj1) );
// find the partition to which these nodes belong
nPart0 = pLcr->pInToOutPart[(int)pObj0->pNext];
nPart1 = pLcr->pInToOutPart[(int)pObj1->pNext];
// if this is the result of refinement of the class created const-1 nodes
// the nodes may end up in different partions - we assume them equivalent
if ( nPart0 != nPart1 )
{
assert( 0 );
return 1;
}
assert( nPart0 == nPart1 );
pFraig = Vec_PtrEntry( pLcr->vFraigs, nPart0 );
// get the fraig outputs
pOut0 = Aig_ManPo( pFraig, pLcr->pInToOutNum[(int)pObj0->pNext] );
pOut1 = Aig_ManPo( pFraig, pLcr->pInToOutNum[(int)pObj1->pNext] );
return Aig_ObjFanin0(pOut0) == Aig_ObjFanin0(pOut1);
}
/**Function*************************************************************
Synopsis [Compares the node with a constant after partioned fraiging.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fra_LcrNodeIsConst( Aig_Obj_t * pObj )
{
Fra_Man_t * pTemp = pObj->pData;
Fra_Lcr_t * pLcr = (Fra_Lcr_t *)pTemp->pBmc;
Aig_Man_t * pFraig;
Aig_Obj_t * pOut;
int nPart;
assert( Aig_ObjIsPi(pObj) );
// find the partition to which these nodes belong
nPart = pLcr->pInToOutPart[(int)pObj->pNext];
pFraig = Vec_PtrEntry( pLcr->vFraigs, nPart );
// get the fraig outputs
pOut = Aig_ManPo( pFraig, pLcr->pInToOutNum[(int)pObj->pNext] );
return Aig_ObjFanin0(pOut) == Aig_ManConst1(pFraig);
}
/**Function*************************************************************
Synopsis [Give the AIG and classes, reduces AIG for partitioning.]
Description [Ignores registers that are not in the classes.
Places candidate equivalent classes of registers into single outputs
(for ease of partitioning). The resulting combinational AIG contains
outputs in the same order as equivalence classes of registers,
followed by constant-1 registers. Preserves the set of all inputs.
Complemented attributes of the outputs do not matter because we need
then only for collecting the structural info.]
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Fra_LcrDeriveAigForPartitioning( Fra_Lcr_t * pLcr )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj, * pObjPo, * pObjNew, ** ppClass, * pMiter;
int i, c, Offset;
// remember the numbers of the inputs of the original AIG
Aig_ManForEachPi( pLcr->pAig, pObj, i )
{
pObj->pData = pLcr;
pObj->pNext = (Aig_Obj_t *)i;
}
// compute the LO/LI offset
Offset = Aig_ManPoNum(pLcr->pAig) - Aig_ManPiNum(pLcr->pAig);
// create the PIs
Aig_ManCleanData( pLcr->pAig );
pNew = Aig_ManStartFrom( pLcr->pAig );
// go over the equivalence classes
Vec_PtrForEachEntry( pLcr->pCla->vClasses, ppClass, i )
{
pMiter = Aig_ManConst0(pNew);
for ( c = 0; ppClass[c]; c++ )
{
assert( Aig_ObjIsPi(ppClass[c]) );
pObjPo = Aig_ManPo( pLcr->pAig, Offset+(int)ppClass[c]->pNext );
pObjNew = Aig_ManDup_rec( pNew, pLcr->pAig, Aig_ObjFanin0(pObjPo) );
pMiter = Aig_Exor( pNew, pMiter, pObjNew );
}
Aig_ObjCreatePo( pNew, pMiter );
}
// go over the constant candidates
Vec_PtrForEachEntry( pLcr->pCla->vClasses1, pObj, i )
{
assert( Aig_ObjIsPi(pObj) );
pObjPo = Aig_ManPo( pLcr->pAig, Offset+(int)pObj->pNext );
pMiter = Aig_ManDup_rec( pNew, pLcr->pAig, Aig_ObjFanin0(pObjPo) );
Aig_ObjCreatePo( pNew, pMiter );
}
return pNew;
}
/**Function*************************************************************
Synopsis [Remaps partitions into the inputs of original AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_LcrRemapPartitions( Vec_Ptr_t * vParts, Fra_Cla_t * pCla, int * pInToOutPart, int * pInToOutNum )
{
Vec_Int_t * vOne, * vOneNew;
Aig_Obj_t ** ppClass, * pObjPi;
int Out, Offset, i, k, c;
// compute the LO/LI offset
Offset = Aig_ManPoNum(pCla->pAig) - Aig_ManPiNum(pCla->pAig);
Vec_PtrForEachEntry( vParts, vOne, i )
{
vOneNew = Vec_IntAlloc( Vec_IntSize(vOne) );
Vec_IntForEachEntry( vOne, Out, k )
{
if ( Out < Vec_PtrSize(pCla->vClasses) )
{
ppClass = Vec_PtrEntry( pCla->vClasses, Out );
for ( c = 0; ppClass[c]; c++ )
{
pInToOutPart[(int)ppClass[c]->pNext] = i;
pInToOutNum[(int)ppClass[c]->pNext] = Vec_IntSize(vOneNew);
Vec_IntPush( vOneNew, Offset+(int)ppClass[c]->pNext );
}
}
else
{
pObjPi = Vec_PtrEntry( pCla->vClasses1, Out - Vec_PtrSize(pCla->vClasses) );
pInToOutPart[(int)pObjPi->pNext] = i;
pInToOutNum[(int)pObjPi->pNext] = Vec_IntSize(vOneNew);
Vec_IntPush( vOneNew, Offset+(int)pObjPi->pNext );
}
}
// replace the class
Vec_PtrWriteEntry( vParts, i, vOneNew );
Vec_IntFree( vOne );
}
}
/**Function*************************************************************
Synopsis [Creates AIG of one partition with speculative reduction.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Obj_t * Fra_LcrCreatePart_rec( Fra_Cla_t * pCla, Aig_Man_t * pNew, Aig_Man_t * p, Aig_Obj_t * pObj )
{
assert( !Aig_IsComplement(pObj) );
if ( Aig_ObjIsTravIdCurrent(p, pObj) )
return pObj->pData;
Aig_ObjSetTravIdCurrent(p, pObj);
if ( Aig_ObjIsPi(pObj) )
{
// Aig_Obj_t * pRepr = Fra_ClassObjRepr(pObj);
Aig_Obj_t * pRepr = pCla->pMemRepr[pObj->Id];
if ( pRepr == NULL )
pObj->pData = Aig_ObjCreatePi( pNew );
else
{
pObj->pData = Fra_LcrCreatePart_rec( pCla, pNew, p, pRepr );
pObj->pData = Aig_NotCond( pObj->pData, pRepr->fPhase ^ pObj->fPhase );
}
return pObj->pData;
}
Fra_LcrCreatePart_rec( pCla, pNew, p, Aig_ObjFanin0(pObj) );
Fra_LcrCreatePart_rec( pCla, pNew, p, Aig_ObjFanin1(pObj) );
return pObj->pData = Aig_And( pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
}
/**Function*************************************************************
Synopsis [Creates AIG of one partition with speculative reduction.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Fra_LcrCreatePart( Fra_Lcr_t * p, Vec_Int_t * vPart )
{
Aig_Man_t * pNew;
Aig_Obj_t * pObj, * pObjNew;
int Out, i;
// create new AIG for this partition
pNew = Aig_ManStartFrom( p->pAig );
Aig_ManIncrementTravId( p->pAig );
Aig_ObjSetTravIdCurrent( p->pAig, Aig_ManConst1(p->pAig) );
Aig_ManConst1(p->pAig)->pData = Aig_ManConst1(pNew);
Vec_IntForEachEntry( vPart, Out, i )
{
pObj = Aig_ManPo( p->pAig, Out );
if ( pObj->fMarkA )
{
pObjNew = Fra_LcrCreatePart_rec( p->pCla, pNew, p->pAig, Aig_ObjFanin0(pObj) );
pObjNew = Aig_NotCond( pObjNew, Aig_ObjFaninC0(pObj) );
}
else
pObjNew = Aig_ManConst1( pNew );
Aig_ObjCreatePo( pNew, pObjNew );
}
return pNew;
}
/**Function*************************************************************
Synopsis [Marks the nodes belonging to the equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_ClassNodesMark( Fra_Lcr_t * p )
{
Aig_Obj_t * pObj, ** ppClass;
int i, c, Offset;
// compute the LO/LI offset
Offset = Aig_ManPoNum(p->pCla->pAig) - Aig_ManPiNum(p->pCla->pAig);
// mark the nodes remaining in the classes
Vec_PtrForEachEntry( p->pCla->vClasses1, pObj, i )
{
pObj = Aig_ManPo( p->pCla->pAig, Offset+(int)pObj->pNext );
pObj->fMarkA = 1;
}
Vec_PtrForEachEntry( p->pCla->vClasses, ppClass, i )
{
for ( c = 0; ppClass[c]; c++ )
{
pObj = Aig_ManPo( p->pCla->pAig, Offset+(int)ppClass[c]->pNext );
pObj->fMarkA = 1;
}
}
}
/**Function*************************************************************
Synopsis [Unmarks the nodes belonging to the equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_ClassNodesUnmark( Fra_Lcr_t * p )
{
Aig_Obj_t * pObj, ** ppClass;
int i, c, Offset;
// compute the LO/LI offset
Offset = Aig_ManPoNum(p->pCla->pAig) - Aig_ManPiNum(p->pCla->pAig);
// mark the nodes remaining in the classes
Vec_PtrForEachEntry( p->pCla->vClasses1, pObj, i )
{
pObj = Aig_ManPo( p->pCla->pAig, Offset+(int)pObj->pNext );
pObj->fMarkA = 0;
}
Vec_PtrForEachEntry( p->pCla->vClasses, ppClass, i )
{
for ( c = 0; ppClass[c]; c++ )
{
pObj = Aig_ManPo( p->pCla->pAig, Offset+(int)ppClass[c]->pNext );
pObj->fMarkA = 0;
}
}
}
/**Function*************************************************************
Synopsis [Performs choicing of the AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Fra_FraigLatchCorrespondence( Aig_Man_t * pAig, int nFramesP, int nConfMax, int fVerbose, int * pnIter )
{
int nPartSize = 200;
int fReprSelect = 0;
Fra_Lcr_t * p;
Fra_Man_t * pTemp;
Aig_Man_t * pAigPart, * pAigNew = NULL;
Vec_Int_t * vPart;
Aig_Obj_t * pObj = Aig_ManObj(pAig, 2078);
int i, nIter, clk = clock(), clk2, clk3;
if ( Aig_ManNodeNum(pAig) == 0 )
{
if ( pnIter ) *pnIter = 0;
return Aig_ManDup(pAig, 1);
}
assert( Aig_ManLatchNum(pAig) == 0 );
assert( Aig_ManRegNum(pAig) > 0 );
// start the manager
p = Lcr_ManAlloc( pAig );
p->nFramesP = nFramesP;
p->fVerbose = fVerbose;
// simulate the AIG
clk2 = clock();
if ( fVerbose )
printf( "Simulating AIG with %d nodes for %d cycles ... ", Aig_ManNodeNum(pAig), nFramesP + 32 );
pTemp = Fra_LcrAigPrepare( p->pAig );
pTemp->pBmc = (Fra_Bmc_t *)p;
pTemp->pSml = Fra_SmlSimulateSeq( p->pAig, p->nFramesP, 32, 1 );
if ( fVerbose )
{
PRT( "Time", clock() - clk2 );
p->timeSim += clock() - clk2;
}
// get preliminary info about equivalence classes
pTemp->pCla = p->pCla = Fra_ClassesStart( p->pAig );
Fra_ClassesPrepare( p->pCla, 1 );
p->pCla->pFuncNodeIsConst = Fra_LcrNodeIsConst;
p->pCla->pFuncNodesAreEqual = Fra_LcrNodesAreEqual;
Fra_SmlStop( pTemp->pSml );
// partition the AIG for latch correspondence computation
clk2 = clock();
if ( fVerbose )
printf( "Partitioning AIG ... " );
pAigPart = Fra_LcrDeriveAigForPartitioning( p );
p->vParts = (Vec_Ptr_t *)Aig_ManPartitionSmart( pAigPart, nPartSize, 0, NULL );
Fra_LcrRemapPartitions( p->vParts, p->pCla, p->pInToOutPart, p->pInToOutNum );
Aig_ManStop( pAigPart );
if ( fVerbose )
{
PRT( "Time", clock() - clk2 );
p->timePart += clock() - clk2;
}
// get the initial stats
p->nLitsBeg = Fra_ClassesCountLits( p->pCla );
p->nNodesBeg = Aig_ManNodeNum(p->pAig);
p->nRegsBeg = Aig_ManRegNum(p->pAig);
// perforn interative reduction of the partitions
p->fRefining = 1;
for ( nIter = 0; p->fRefining; nIter++ )
{
p->fRefining = 0;
clk3 = clock();
// derive AIGs for each partition
Fra_ClassNodesMark( p );
Vec_PtrClear( p->vFraigs );
Vec_PtrForEachEntry( p->vParts, vPart, i )
{
clk2 = clock();
pAigPart = Fra_LcrCreatePart( p, vPart );
p->timeTrav += clock() - clk2;
clk2 = clock();
pAigNew = Fra_FraigEquivence( pAigPart, nConfMax );
p->timeFraig += clock() - clk2;
Vec_PtrPush( p->vFraigs, pAigNew );
Aig_ManStop( pAigPart );
}
Fra_ClassNodesUnmark( p );
// report the intermediate results
if ( fVerbose )
{
printf( "%3d : Const = %6d. Class = %6d. L = %6d. Part = %3d. ",
nIter, Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses),
Fra_ClassesCountLits(p->pCla), Vec_PtrSize(p->vParts) );
PRT( "T", clock() - clk3 );
}
// refine the classes
Fra_LcrAigPrepareTwo( p->pAig, pTemp );
if ( Fra_ClassesRefine( p->pCla ) )
p->fRefining = 1;
if ( Fra_ClassesRefine1( p->pCla, 0, NULL ) )
p->fRefining = 1;
// clean the fraigs
Vec_PtrForEachEntry( p->vFraigs, pAigPart, i )
Aig_ManStop( pAigPart );
// repartition if needed
if ( 1 )
{
clk2 = clock();
Vec_VecFree( (Vec_Vec_t *)p->vParts );
pAigPart = Fra_LcrDeriveAigForPartitioning( p );
p->vParts = (Vec_Ptr_t *)Aig_ManPartitionSmart( pAigPart, nPartSize, 0, NULL );
Fra_LcrRemapPartitions( p->vParts, p->pCla, p->pInToOutPart, p->pInToOutNum );
Aig_ManStop( pAigPart );
p->timePart += clock() - clk2;
}
}
free( pTemp );
p->nIters = nIter;
// move the classes into representatives and reduce AIG
clk2 = clock();
// Fra_ClassesPrint( p->pCla, 1 );
if ( fReprSelect )
Fra_ClassesSelectRepr( p->pCla );
Fra_ClassesCopyReprs( p->pCla, NULL );
pAigNew = Aig_ManDupRepr( p->pAig );
Aig_ManSeqCleanup( pAigNew );
// Aig_ManCountMergeRegs( pAigNew );
p->timeUpdate += clock() - clk2;
p->timeTotal = clock() - clk;
// get the final stats
p->nLitsEnd = Fra_ClassesCountLits( p->pCla );
p->nNodesEnd = Aig_ManNodeNum(pAigNew);
p->nRegsEnd = Aig_ManRegNum(pAigNew);
Lcr_ManFree( p );
if ( pnIter ) *pnIter = nIter;
return pAigNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...@@ -181,6 +181,8 @@ Aig_Man_t * Fra_ManPrepareComb( Fra_Man_t * p ) ...@@ -181,6 +181,8 @@ Aig_Man_t * Fra_ManPrepareComb( Fra_Man_t * p )
assert( p->pManFraig == NULL ); assert( p->pManFraig == NULL );
// start the fraig package // start the fraig package
pManFraig = Aig_ManStart( Aig_ManObjIdMax(p->pManAig) + 1 ); pManFraig = Aig_ManStart( Aig_ManObjIdMax(p->pManAig) + 1 );
pManFraig->nRegs = p->pManAig->nRegs;
pManFraig->nAsserts = p->pManAig->nAsserts;
// set the pointers to the available fraig nodes // set the pointers to the available fraig nodes
Fra_ObjSetFraig( Aig_ManConst1(p->pManAig), 0, Aig_ManConst1(pManFraig) ); Fra_ObjSetFraig( Aig_ManConst1(p->pManAig), 0, Aig_ManConst1(pManFraig) );
Aig_ManForEachPi( p->pManAig, pObj, i ) Aig_ManForEachPi( p->pManAig, pObj, i )
...@@ -271,9 +273,9 @@ void Fra_ManPrint( Fra_Man_t * p ) ...@@ -271,9 +273,9 @@ void Fra_ManPrint( Fra_Man_t * p )
{ {
double nMemory = 1.0*Aig_ManObjIdMax(p->pManAig)*(p->pSml->nWordsTotal*sizeof(unsigned)+6*sizeof(void*))/(1<<20); double nMemory = 1.0*Aig_ManObjIdMax(p->pManAig)*(p->pSml->nWordsTotal*sizeof(unsigned)+6*sizeof(void*))/(1<<20);
printf( "SimWord = %d. Round = %d. Mem = %0.2f Mb. LitBeg = %d. LitEnd = %d. (%6.2f %%).\n", printf( "SimWord = %d. Round = %d. Mem = %0.2f Mb. LitBeg = %d. LitEnd = %d. (%6.2f %%).\n",
p->pPars->nSimWords, p->pSml->nSimRounds, nMemory, p->nLitsBeg, p->nLitsEnd, 100.0*p->nLitsEnd/p->nLitsBeg ); p->pPars->nSimWords, p->pSml->nSimRounds, nMemory, p->nLitsBeg, p->nLitsEnd, 100.0*p->nLitsEnd/(p->nLitsBeg?p->nLitsBeg:1) );
printf( "Proof = %d. Cex = %d. Fail = %d. FailReal = %d. Zero = %d. C-lim = %d. Vars = %d.\n", printf( "Proof = %d. Cex = %d. Fail = %d. FailReal = %d. C-lim = %d. ImpRatio = %6.2f %%\n",
p->nSatProof, p->nSatCallsSat, p->nSatFails, p->nSatFailsReal, p->nLitsZero, p->pPars->nBTLimitNode, p->nSatVars ); p->nSatProof, p->nSatCallsSat, p->nSatFails, p->nSatFailsReal, p->pPars->nBTLimitNode, Fra_ImpComputeStateSpaceRatio(p) );
printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n", printf( "NBeg = %d. NEnd = %d. (Gain = %6.2f %%). RBeg = %d. REnd = %d. (Gain = %6.2f %%).\n",
p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/p->nNodesBeg, p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/p->nNodesBeg,
p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/p->nRegsBeg ); p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/p->nRegsBeg );
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose ) int Fra_FraigSec2( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose )
{ {
Aig_Man_t * pNew; Aig_Man_t * pNew;
int nFrames, RetValue, nIter, clk, clkTotal = clock(); int nFrames, RetValue, nIter, clk, clkTotal = clock();
...@@ -48,7 +48,7 @@ int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose ...@@ -48,7 +48,7 @@ int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose
{ {
nFrames = nFramesFix; nFrames = nFramesFix;
// perform seq sweeping for one frame number // perform seq sweeping for one frame number
pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, fLatchCorr, fVeryVerbose, &nIter ); pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, fLatchCorr, 0, fVeryVerbose, &nIter );
} }
else else
{ {
...@@ -56,7 +56,7 @@ int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose ...@@ -56,7 +56,7 @@ int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose
for ( nFrames = 1; ; nFrames++ ) for ( nFrames = 1; ; nFrames++ )
{ {
clk = clock(); clk = clock();
pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, fLatchCorr, fVeryVerbose, &nIter ); pNew = Fra_FraigInduction( p, 0, nFrames, 0, 0, 0, fLatchCorr, 0, fVeryVerbose, &nIter );
RetValue = Fra_FraigMiterStatus( pNew ); RetValue = Fra_FraigMiterStatus( pNew );
if ( fVerbose ) if ( fVerbose )
{ {
...@@ -89,6 +89,136 @@ PRT( "Time", clock() - clkTotal ); ...@@ -89,6 +89,136 @@ PRT( "Time", clock() - clkTotal );
} }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fRetimeFirst, int fVerbose, int fVeryVerbose )
{
Aig_Man_t * pNew, * pTemp;
int nFrames, RetValue, nIter, clk, clkTotal = clock();
int fLatchCorr = 0;
pNew = Aig_ManDup( p, 1 );
if ( fVerbose )
{
printf( "Original miter: Latches = %5d. Nodes = %6d.\n",
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
}
//Aig_ManDumpBlif( pNew, "after.blif" );
// perform sequential cleanup
clk = clock();
pNew = Aig_ManReduceLaches( pNew, 0 );
pNew = Aig_ManConstReduce( pNew, 0 );
if ( fVerbose )
{
printf( "Sequential cleanup: Latches = %5d. Nodes = %6d. ",
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
PRT( "Time", clock() - clk );
}
// perform forward retiming
if ( fRetimeFirst )
{
clk = clock();
pNew = Rtm_ManRetime( pTemp = pNew, 1, 1000, 0 );
Aig_ManStop( pTemp );
if ( fVerbose )
{
printf( "Forward retiming: Latches = %5d. Nodes = %6d. ",
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
PRT( "Time", clock() - clk );
}
}
// run latch correspondence
clk = clock();
pNew = Aig_ManDup( pTemp = pNew, 1 );
Aig_ManStop( pTemp );
pNew = Fra_FraigLatchCorrespondence( pTemp = pNew, 0, 100000, fVeryVerbose, &nIter );
Aig_ManStop( pTemp );
if ( fVerbose )
{
printf( "Latch-corr (I=%3d): Latches = %5d. Nodes = %6d. ",
nIter, Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
PRT( "Time", clock() - clk );
}
// perform fraiging
clk = clock();
pNew = Fra_FraigEquivence( pTemp = pNew, 1000 );
Aig_ManStop( pTemp );
if ( fVerbose )
{
printf( "Fraiging: Latches = %5d. Nodes = %6d. ",
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
PRT( "Time", clock() - clk );
}
// perform seq sweeping while increasing the number of frames
RetValue = Fra_FraigMiterStatus( pNew );
if ( RetValue == -1 )
for ( nFrames = 1; ; nFrames *= 2 )
{
clk = clock();
pNew = Fra_FraigInduction( pTemp = pNew, 0, nFrames, 0, 0, 0, fLatchCorr, 0, fVeryVerbose, &nIter );
Aig_ManStop( pTemp );
RetValue = Fra_FraigMiterStatus( pNew );
if ( fVerbose )
{
printf( "K-step (K=%2d,I=%3d): Latches = %5d. Nodes = %6d. ",
nFrames, nIter, Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
PRT( "Time", clock() - clk );
}
if ( RetValue != -1 )
break;
// perform rewriting
clk = clock();
pNew = Aig_ManDup( pTemp = pNew, 1 );
Aig_ManStop( pTemp );
pNew = Dar_ManRewriteDefault( pTemp = pNew );
if ( fVerbose )
{
printf( "Rewriting: Latches = %5d. Nodes = %6d. ",
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
PRT( "Time", clock() - clk );
}
// perform retiming
clk = clock();
pNew = Rtm_ManRetime( pTemp = pNew, 1, 1000, 0 );
Aig_ManStop( pTemp );
pNew = Aig_ManDup( pTemp = pNew, 1 );
Aig_ManStop( pTemp );
if ( fVerbose )
{
printf( "Forward retiming: Latches = %5d. Nodes = %6d. ",
Aig_ManRegNum(pNew), Aig_ManNodeNum(pNew) );
PRT( "Time", clock() - clk );
}
}
// get the miter status
RetValue = Fra_FraigMiterStatus( pNew );
Aig_ManStop( pNew );
// report the miter
if ( RetValue == 1 )
printf( "Networks are equivalent. " );
else if ( RetValue == 0 )
printf( "Networks are NOT EQUIVALENT. " );
else
printf( "Networks are UNDECIDED. " );
PRT( "Time", clock() - clkTotal );
return RetValue;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -199,7 +199,7 @@ void Fra_SmlSavePattern( Fra_Man_t * p ) ...@@ -199,7 +199,7 @@ void Fra_SmlSavePattern( Fra_Man_t * p )
Aig_ManForEachPi( p->pManFraig, pObj, i ) Aig_ManForEachPi( p->pManFraig, pObj, i )
if ( p->pSat->model.ptr[Fra_ObjSatNum(pObj)] == l_True ) if ( p->pSat->model.ptr[Fra_ObjSatNum(pObj)] == l_True )
Aig_InfoSetBit( p->pPatWords, i ); Aig_InfoSetBit( p->pPatWords, i );
/*
if ( p->vCex ) if ( p->vCex )
{ {
Vec_IntClear( p->vCex ); Vec_IntClear( p->vCex );
...@@ -208,7 +208,6 @@ void Fra_SmlSavePattern( Fra_Man_t * p ) ...@@ -208,7 +208,6 @@ void Fra_SmlSavePattern( Fra_Man_t * p )
for ( i = Aig_ManPiNum(p->pManFraig) - Aig_ManRegNum(p->pManFraig); i < Aig_ManPiNum(p->pManFraig); i++ ) for ( i = Aig_ManPiNum(p->pManFraig) - Aig_ManRegNum(p->pManFraig); i < Aig_ManPiNum(p->pManFraig); i++ )
Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) ); Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) );
} }
*/
/* /*
printf( "Pattern: " ); printf( "Pattern: " );
...@@ -608,7 +607,7 @@ void Fra_SmlResimulate( Fra_Man_t * p ) ...@@ -608,7 +607,7 @@ void Fra_SmlResimulate( Fra_Man_t * p )
return; return;
clk = clock(); clk = clock();
nChanges = Fra_ClassesRefine( p->pCla ); nChanges = Fra_ClassesRefine( p->pCla );
nChanges += Fra_ClassesRefine1( p->pCla ); nChanges += Fra_ClassesRefine1( p->pCla, 1, NULL );
if ( p->pCla->vImps ) if ( p->pCla->vImps )
nChanges += Fra_ImpRefineUsingCex( p, p->pCla->vImps ); nChanges += Fra_ImpRefineUsingCex( p, p->pCla->vImps );
p->timeRef += clock() - clk; p->timeRef += clock() - clk;
...@@ -652,7 +651,7 @@ printf( "Starting classes = %5d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses ...@@ -652,7 +651,7 @@ printf( "Starting classes = %5d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses
return; return;
clk = clock(); clk = clock();
nChanges = Fra_ClassesRefine( p->pCla ); nChanges = Fra_ClassesRefine( p->pCla );
nChanges += Fra_ClassesRefine1( p->pCla ); nChanges += Fra_ClassesRefine1( p->pCla, 1, NULL );
p->timeRef += clock() - clk; p->timeRef += clock() - clk;
if ( fVerbose ) if ( fVerbose )
printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses), nChanges, Fra_ClassesCountLits(p->pCla) ); printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses), nChanges, Fra_ClassesCountLits(p->pCla) );
...@@ -663,7 +662,7 @@ printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize( ...@@ -663,7 +662,7 @@ printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(
return; return;
clk = clock(); clk = clock();
nChanges = Fra_ClassesRefine( p->pCla ); nChanges = Fra_ClassesRefine( p->pCla );
nChanges += Fra_ClassesRefine1( p->pCla ); nChanges += Fra_ClassesRefine1( p->pCla, 1, NULL );
p->timeRef += clock() - clk; p->timeRef += clock() - clk;
if ( fVerbose ) if ( fVerbose )
...@@ -677,7 +676,7 @@ printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize( ...@@ -677,7 +676,7 @@ printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(
return; return;
clk = clock(); clk = clock();
nChanges = Fra_ClassesRefine( p->pCla ); nChanges = Fra_ClassesRefine( p->pCla );
nChanges += Fra_ClassesRefine1( p->pCla ); nChanges += Fra_ClassesRefine1( p->pCla, 1, NULL );
p->timeRef += clock() - clk; p->timeRef += clock() - clk;
if ( fVerbose ) if ( fVerbose )
printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses), nChanges, Fra_ClassesCountLits(p->pCla) ); printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses), nChanges, Fra_ClassesCountLits(p->pCla) );
...@@ -704,7 +703,6 @@ printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize( ...@@ -704,7 +703,6 @@ printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(
Fra_Sml_t * Fra_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame ) Fra_Sml_t * Fra_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame )
{ {
Fra_Sml_t * p; Fra_Sml_t * p;
assert( Aig_ManObjIdMax(pAig) + 1 < (1 << 16) );
p = (Fra_Sml_t *)malloc( sizeof(Fra_Sml_t) + sizeof(unsigned) * (Aig_ManObjIdMax(pAig) + 1) * (nPref + nFrames) * nWordsFrame ); p = (Fra_Sml_t *)malloc( sizeof(Fra_Sml_t) + sizeof(unsigned) * (Aig_ManObjIdMax(pAig) + 1) * (nPref + nFrames) * nWordsFrame );
memset( p, 0, sizeof(Fra_Sml_t) + sizeof(unsigned) * (nPref + nFrames) * nWordsFrame ); memset( p, 0, sizeof(Fra_Sml_t) + sizeof(unsigned) * (nPref + nFrames) * nWordsFrame );
p->pAig = pAig; p->pAig = pAig;
......
...@@ -5,6 +5,7 @@ SRC += src/aig/fra/fraBmc.c \ ...@@ -5,6 +5,7 @@ SRC += src/aig/fra/fraBmc.c \
src/aig/fra/fraCore.c \ src/aig/fra/fraCore.c \
src/aig/fra/fraImp.c \ src/aig/fra/fraImp.c \
src/aig/fra/fraInd.c \ src/aig/fra/fraInd.c \
src/aig/fra/fraLcr.c \
src/aig/fra/fraMan.c \ src/aig/fra/fraMan.c \
src/aig/fra/fraSat.c \ src/aig/fra/fraSat.c \
src/aig/fra/fraSec.c \ src/aig/fra/fraSec.c \
......
...@@ -869,6 +869,7 @@ extern void * Abc_NtkAttrFree( Abc_Ntk_t * pNtk, int Attr, int fFree ...@@ -869,6 +869,7 @@ extern void * Abc_NtkAttrFree( Abc_Ntk_t * pNtk, int Attr, int fFree
extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk ); extern void Abc_NtkIncrementTravId( Abc_Ntk_t * pNtk );
extern void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk ); extern void Abc_NtkOrderCisCos( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetCubePairNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetLitNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetLitFactNum( Abc_Ntk_t * pNtk );
extern int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk ); extern int Abc_NtkGetBddNodeNum( Abc_Ntk_t * pNtk );
......
...@@ -148,6 +148,33 @@ int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk ) ...@@ -148,6 +148,33 @@ int Abc_NtkGetCubeNum( Abc_Ntk_t * pNtk )
/**Function************************************************************* /**Function*************************************************************
Synopsis [Reads the number of cubes of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkGetCubePairNum( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pNode;
int i, nCubes, nCubePairs = 0;
assert( Abc_NtkHasSop(pNtk) );
Abc_NtkForEachNode( pNtk, pNode, i )
{
if ( Abc_NodeIsConst(pNode) )
continue;
assert( pNode->pData );
nCubes = Abc_SopGetCubeNum( pNode->pData );
nCubePairs += nCubes * (nCubes - 1) / 2;
}
return nCubePairs;
}
/**Function*************************************************************
Synopsis [Reads the number of literals in the SOPs of the nodes.] Synopsis [Reads the number of literals in the SOPs of the nodes.]
Description [] Description []
......
...@@ -123,6 +123,7 @@ static int Abc_CommandIFraig ( Abc_Frame_t * pAbc, int argc, char ** arg ...@@ -123,6 +123,7 @@ static int Abc_CommandIFraig ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandDFraig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandDFraig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCSweep ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCSweep ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandDProve ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandHaig ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandHaig ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandMini ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandBmc ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBmc ( Abc_Frame_t * pAbc, int argc, char ** argv );
...@@ -166,6 +167,7 @@ static int Abc_CommandRetime ( Abc_Frame_t * pAbc, int argc, char ** arg ...@@ -166,6 +167,7 @@ static int Abc_CommandRetime ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandSeqFpga ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSeqFpga ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSeqMap ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSeqMap ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSeqSweep ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSeqSweep ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandLcorr ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandSeqCleanup ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandSeqCleanup ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandCycle ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCycle ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandXsim ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandXsim ( Abc_Frame_t * pAbc, int argc, char ** argv );
...@@ -326,12 +328,11 @@ void Abc_Init( Abc_Frame_t * pAbc ) ...@@ -326,12 +328,11 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Sequential", "init", Abc_CommandInit, 1 ); Cmd_CommandAdd( pAbc, "Sequential", "init", Abc_CommandInit, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "zero", Abc_CommandZero, 1 ); Cmd_CommandAdd( pAbc, "Sequential", "zero", Abc_CommandZero, 1 );
// Cmd_CommandAdd( pAbc, "Sequential", "pipe", Abc_CommandPipe, 1 ); // Cmd_CommandAdd( pAbc, "Sequential", "pipe", Abc_CommandPipe, 1 );
// Cmd_CommandAdd( pAbc, "Sequential", "seq", Abc_CommandSeq, 1 );
// Cmd_CommandAdd( pAbc, "Sequential", "unseq", Abc_CommandUnseq, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 ); Cmd_CommandAdd( pAbc, "Sequential", "retime", Abc_CommandRetime, 1 );
// Cmd_CommandAdd( pAbc, "Sequential", "sfpga", Abc_CommandSeqFpga, 1 ); // Cmd_CommandAdd( pAbc, "Sequential", "sfpga", Abc_CommandSeqFpga, 1 );
// Cmd_CommandAdd( pAbc, "Sequential", "smap", Abc_CommandSeqMap, 1 ); // Cmd_CommandAdd( pAbc, "Sequential", "smap", Abc_CommandSeqMap, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "ssweep", Abc_CommandSeqSweep, 1 ); Cmd_CommandAdd( pAbc, "Sequential", "ssweep", Abc_CommandSeqSweep, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "lcorr", Abc_CommandLcorr, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "scleanup", Abc_CommandSeqCleanup, 1 ); Cmd_CommandAdd( pAbc, "Sequential", "scleanup", Abc_CommandSeqCleanup, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "cycle", Abc_CommandCycle, 1 ); Cmd_CommandAdd( pAbc, "Sequential", "cycle", Abc_CommandCycle, 1 );
Cmd_CommandAdd( pAbc, "Sequential", "xsim", Abc_CommandXsim, 0 ); Cmd_CommandAdd( pAbc, "Sequential", "xsim", Abc_CommandXsim, 0 );
...@@ -339,6 +340,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) ...@@ -339,6 +340,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 ); Cmd_CommandAdd( pAbc, "Verification", "cec", Abc_CommandCec, 0 );
Cmd_CommandAdd( pAbc, "Verification", "sec", Abc_CommandSec, 0 ); Cmd_CommandAdd( pAbc, "Verification", "sec", Abc_CommandSec, 0 );
Cmd_CommandAdd( pAbc, "Verification", "dsec", Abc_CommandDSec, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dsec", Abc_CommandDSec, 0 );
Cmd_CommandAdd( pAbc, "Verification", "dprove", Abc_CommandDProve, 0 );
Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "sat", Abc_CommandSat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 ); Cmd_CommandAdd( pAbc, "Verification", "dsat", Abc_CommandDSat, 0 );
Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 ); Cmd_CommandAdd( pAbc, "Verification", "prove", Abc_CommandProve, 1 );
...@@ -2588,22 +2590,34 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -2588,22 +2590,34 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv )
p = ALLOC( Fxu_Data_t, 1 ); p = ALLOC( Fxu_Data_t, 1 );
memset( p, 0, sizeof(Fxu_Data_t) ); memset( p, 0, sizeof(Fxu_Data_t) );
// set the defaults // set the defaults
p->nPairsMax = 30000; p->nSingleMax = 20000;
p->nNodesExt = 10000; p->nPairsMax = 30000;
p->fOnlyS = 0; p->nNodesExt = 10000;
p->fOnlyD = 0; p->fOnlyS = 0;
p->fUse0 = 0; p->fOnlyD = 0;
p->fUseCompl = 1; p->fUse0 = 0;
p->fVerbose = 0; p->fUseCompl = 1;
p->fVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( (c = Extra_UtilGetopt(argc, argv, "LNsdzcvh")) != EOF ) while ( (c = Extra_UtilGetopt(argc, argv, "SDNsdzcvh")) != EOF )
{ {
switch (c) switch (c)
{ {
case 'L': case 'S':
if ( globalUtilOptind >= argc ) if ( globalUtilOptind >= argc )
{ {
fprintf( pErr, "Command line switch \"-L\" should be followed by an integer.\n" ); fprintf( pErr, "Command line switch \"-S\" should be followed by an integer.\n" );
goto usage;
}
p->nSingleMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( p->nSingleMax < 0 )
goto usage;
break;
case 'D':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-D\" should be followed by an integer.\n" );
goto usage; goto usage;
} }
p->nPairsMax = atoi(argv[globalUtilOptind]); p->nPairsMax = atoi(argv[globalUtilOptind]);
...@@ -2643,7 +2657,7 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -2643,7 +2657,7 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv )
default: default:
goto usage; goto usage;
} }
} }
if ( pNtk == NULL ) if ( pNtk == NULL )
{ {
...@@ -2673,10 +2687,11 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -2673,10 +2687,11 @@ int Abc_CommandFastExtract( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: usage:
fprintf( pErr, "usage: fx [-N num] [-L num] [-sdzcvh]\n"); fprintf( pErr, "usage: fx [-S num] [-D num] [-N num] [-sdzcvh]\n");
fprintf( pErr, "\t performs unate fast extract on the current network\n"); fprintf( pErr, "\t performs unate fast extract on the current network\n");
fprintf( pErr, "\t-S num : max number of single-cube divisors to consider [default = %d]\n", p->nSingleMax );
fprintf( pErr, "\t-D num : max number of double-cube divisors to consider [default = %d]\n", p->nPairsMax );
fprintf( pErr, "\t-N num : the maximum number of divisors to extract [default = %d]\n", p->nNodesExt ); fprintf( pErr, "\t-N num : the maximum number of divisors to extract [default = %d]\n", p->nNodesExt );
fprintf( pErr, "\t-L num : the maximum number of cube pairs to consider [default = %d]\n", p->nPairsMax );
fprintf( pErr, "\t-s : use only single-cube divisors [default = %s]\n", p->fOnlyS? "yes": "no" ); fprintf( pErr, "\t-s : use only single-cube divisors [default = %s]\n", p->fOnlyS? "yes": "no" );
fprintf( pErr, "\t-d : use only double-cube divisors [default = %s]\n", p->fOnlyD? "yes": "no" ); fprintf( pErr, "\t-d : use only double-cube divisors [default = %s]\n", p->fOnlyD? "yes": "no" );
fprintf( pErr, "\t-z : use zero-weight divisors [default = %s]\n", p->fUse0? "yes": "no" ); fprintf( pErr, "\t-z : use zero-weight divisors [default = %s]\n", p->fUse0? "yes": "no" );
...@@ -6175,7 +6190,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -6175,7 +6190,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc); pErr = Abc_FrameReadErr(pAbc);
// set defaults // set defaults
nLevels = 128; nLevels = 1000;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF )
{ {
...@@ -6293,7 +6308,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -6293,7 +6308,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
} }
// pNtkRes = Abc_NtkDar( pNtk ); // pNtkRes = Abc_NtkDar( pNtk );
pNtkRes = Abc_NtkDarRetime( pNtk, 1000, 1 ); pNtkRes = Abc_NtkDarRetime( pNtk, nLevels, 1 );
if ( pNtkRes == NULL ) if ( pNtkRes == NULL )
{ {
fprintf( pErr, "Command has failed.\n" ); fprintf( pErr, "Command has failed.\n" );
...@@ -8674,7 +8689,7 @@ int Abc_CommandFraigDress( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -8674,7 +8689,7 @@ int Abc_CommandFraigDress( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc); pErr = Abc_FrameReadErr(pAbc);
// set defaults // set defaults
fVerbose = 1; fVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "vh" ) ) != EOF )
{ {
...@@ -10975,12 +10990,12 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -10975,12 +10990,12 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
int nFramesP; int nFramesP;
int nFramesK; int nFramesK;
int nMaxImps; int nMaxImps;
int fExdc;
int fUseImps; int fUseImps;
int fRewrite; int fRewrite;
int fLatchCorr; int fLatchCorr;
int fWriteImps;
int fVerbose; int fVerbose;
extern Abc_Ntk_t * Abc_NtkDarSeqSweep( Abc_Ntk_t * pNtk, int nFramesP, int nFrames, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose ); extern Abc_Ntk_t * Abc_NtkDarSeqSweep( Abc_Ntk_t * pNtk, int nFramesP, int nFrames, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc); pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc); pOut = Abc_FrameReadOut(pAbc);
...@@ -10990,13 +11005,13 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -10990,13 +11005,13 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
nFramesP = 0; nFramesP = 0;
nFramesK = 1; nFramesK = 1;
nMaxImps = 5000; nMaxImps = 5000;
fExdc = 1;
fUseImps = 0; fUseImps = 0;
fRewrite = 0; fRewrite = 0;
fLatchCorr = 0; fLatchCorr = 0;
fWriteImps = 0;
fVerbose = 0; fVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "PFIeirlvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "PFIirlevh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -11033,9 +11048,6 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11033,9 +11048,6 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nMaxImps <= 0 ) if ( nMaxImps <= 0 )
goto usage; goto usage;
break; break;
case 'e':
fExdc ^= 1;
break;
case 'i': case 'i':
fUseImps ^= 1; fUseImps ^= 1;
break; break;
...@@ -11045,6 +11057,9 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11045,6 +11057,9 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'l': case 'l':
fLatchCorr ^= 1; fLatchCorr ^= 1;
break; break;
case 'e':
fWriteImps ^= 1;
break;
case 'v': case 'v':
fVerbose ^= 1; fVerbose ^= 1;
break; break;
...@@ -11069,12 +11084,12 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11069,12 +11084,12 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( !Abc_NtkIsStrash(pNtk) ) if ( !Abc_NtkIsStrash(pNtk) )
{ {
fprintf( pErr, "Sequential sweep works only for structurally hashed networks (run \"strash\").\n" ); printf( "This command works only for structrally hashed networks. Run \"st\".\n" );
return 1; return 0;
} }
// get the new network // get the new network
pNtkRes = Abc_NtkDarSeqSweep( pNtk, nFramesP, nFramesK, nMaxImps, fRewrite, fUseImps, fLatchCorr, fVerbose ); pNtkRes = Abc_NtkDarSeqSweep( pNtk, nFramesP, nFramesK, nMaxImps, fRewrite, fUseImps, fLatchCorr, fWriteImps, fVerbose );
if ( pNtkRes == NULL ) if ( pNtkRes == NULL )
{ {
fprintf( pErr, "Sequential sweeping has failed.\n" ); fprintf( pErr, "Sequential sweeping has failed.\n" );
...@@ -11085,15 +11100,120 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11085,15 +11100,120 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: usage:
fprintf( pErr, "usage: ssweep [-P num] [-F num] [-I num] [-ilrvh]\n" ); fprintf( pErr, "usage: ssweep [-P num] [-F num] [-I num] [-ilrevh]\n" );
fprintf( pErr, "\t performs sequential sweep using K-step induction\n" ); fprintf( pErr, "\t performs sequential sweep using K-step induction\n" );
fprintf( pErr, "\t-P num : number of time frames to use as the prefix [default = %d]\n", nFramesP ); fprintf( pErr, "\t-P num : number of time frames to use as the prefix [default = %d]\n", nFramesP );
fprintf( pErr, "\t-F num : number of time frames for induction (1=simple) [default = %d]\n", nFramesK ); fprintf( pErr, "\t-F num : number of time frames for induction (1=simple) [default = %d]\n", nFramesK );
fprintf( pErr, "\t-I num : max number of implications to consider [default = %d]\n", nMaxImps ); fprintf( pErr, "\t-I num : max number of implications to consider [default = %d]\n", nMaxImps );
// fprintf( pErr, "\t-e : toggle writing EXDC network [default = %s]\n", fExdc? "yes": "no" );
fprintf( pErr, "\t-i : toggle using implications [default = %s]\n", fUseImps? "yes": "no" ); fprintf( pErr, "\t-i : toggle using implications [default = %s]\n", fUseImps? "yes": "no" );
fprintf( pErr, "\t-l : toggle latch correspondence only [default = %s]\n", fLatchCorr? "yes": "no" ); fprintf( pErr, "\t-l : toggle latch correspondence only [default = %s]\n", fLatchCorr? "yes": "no" );
fprintf( pErr, "\t-r : toggle AIG rewriting [default = %s]\n", fRewrite? "yes": "no" ); fprintf( pErr, "\t-r : toggle AIG rewriting [default = %s]\n", fRewrite? "yes": "no" );
fprintf( pErr, "\t-e : toggle writing implications as assertions [default = %s]\n", fWriteImps? "yes": "no" );
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandLcorr( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes;
int c;
int nFramesP;
int nConfMax;
int fVerbose;
extern Abc_Ntk_t * Abc_NtkDarLcorr( Abc_Ntk_t * pNtk, int nFramesP, int nConfMax, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
nFramesP = 0;
nConfMax = 10000;
fVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "PCvh" ) ) != EOF )
{
switch ( c )
{
case 'P':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-P\" should be followed by an integer.\n" );
goto usage;
}
nFramesP = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nFramesP < 0 )
goto usage;
break;
case 'C':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-C\" should be followed by an integer.\n" );
goto usage;
}
nConfMax = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nConfMax < 0 )
goto usage;
break;
case 'v':
fVerbose ^= 1;
break;
case 'h':
goto usage;
default:
goto usage;
}
}
if ( pNtk == NULL )
{
fprintf( pErr, "Empty network.\n" );
return 1;
}
if ( Abc_NtkIsComb(pNtk) )
{
fprintf( pErr, "The network is combinational (run \"fraig\" or \"fraig_sweep\").\n" );
return 1;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
printf( "This command works only for structrally hashed networks. Run \"st\".\n" );
return 0;
}
// get the new network
pNtkRes = Abc_NtkDarLcorr( pNtk, nFramesP, nConfMax, fVerbose );
if ( pNtkRes == NULL )
{
fprintf( pErr, "Sequential sweeping has failed.\n" );
return 1;
}
// replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
return 0;
usage:
fprintf( pErr, "usage: lcorr [-P num] [-C num] [-vh]\n" );
fprintf( pErr, "\t computes latch correspondence using 1-step induction\n" );
fprintf( pErr, "\t-P num : number of time frames to use as the prefix [default = %d]\n", nFramesP );
fprintf( pErr, "\t-C num : max conflict number when proving latch equivalence [default = %d]\n", nConfMax );
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n"); fprintf( pErr, "\t-h : print the command usage\n");
return 1; return 1;
...@@ -11113,12 +11233,12 @@ usage: ...@@ -11113,12 +11233,12 @@ usage:
int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
FILE * pOut, * pErr; FILE * pOut, * pErr;
Abc_Ntk_t * pNtk, * pNtkRes, * pTemp; Abc_Ntk_t * pNtk, * pNtkRes;
int c; int c;
int fLatchSweep; int fLatchSweep;
int fAutoSweep; int fAutoSweep;
int fVerbose; int fVerbose;
extern Abc_Ntk_t * Abc_NtkDarLatchSweep( Abc_Ntk_t * pNtk, int fVerbose ); extern Abc_Ntk_t * Abc_NtkDarLatchSweep( Abc_Ntk_t * pNtk, int fLatchSweep, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc); pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc); pOut = Abc_FrameReadOut(pAbc);
...@@ -11153,23 +11273,13 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11153,23 +11273,13 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
fprintf( pErr, "Empty network.\n" ); fprintf( pErr, "Empty network.\n" );
return 1; return 1;
} }
if ( !Abc_NtkIsLogic(pNtk) ) if ( !Abc_NtkIsStrash(pNtk) )
{ {
fprintf( pErr, "Only works for logic networks.\n" ); fprintf( pErr, "Only works for structrally hashed networks.\n" );
return 1; return 1;
} }
// modify the current network // modify the current network
pNtkRes = Abc_NtkDarLatchSweep( pNtk, fLatchSweep, fVerbose );
// get the new network
pNtkRes = Abc_NtkDup( pNtk );
Abc_NtkCleanupSeq( pNtkRes, 0, fAutoSweep, fVerbose );
if ( fLatchSweep )
{
pNtkRes = Abc_NtkStrash( pTemp = pNtkRes, 0, 0, 0 );
Abc_NtkDelete( pTemp );
pNtkRes = Abc_NtkDarLatchSweep( pTemp = pNtkRes, fVerbose );
Abc_NtkDelete( pTemp );
}
if ( pNtkRes == NULL ) if ( pNtkRes == NULL )
{ {
fprintf( pErr, "Sequential cleanup has failed.\n" ); fprintf( pErr, "Sequential cleanup has failed.\n" );
...@@ -11180,14 +11290,14 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11180,14 +11290,14 @@ int Abc_CommandSeqCleanup( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: usage:
fprintf( pErr, "usage: scleanup [-lavh]\n" ); fprintf( pErr, "usage: scleanup [-lvh]\n" );
fprintf( pErr, "\t performs sequential cleanup\n" ); fprintf( pErr, "\t performs sequential cleanup\n" );
fprintf( pErr, "\t - removes nodes/latches that do not feed into POs\n" ); fprintf( pErr, "\t - removes nodes/latches that do not feed into POs\n" );
fprintf( pErr, "\t - removes stuck-at and identical latches (latch sweep)\n" ); fprintf( pErr, "\t - removes stuck-at and identical latches (latch sweep)\n" );
fprintf( pErr, "\t - replaces autonomous logic by free PI variables\n" ); // fprintf( pErr, "\t - replaces autonomous logic by free PI variables\n" );
fprintf( pErr, "\t (the latter may change sequential behaviour)\n" ); fprintf( pErr, "\t (the latter may change sequential behaviour)\n" );
fprintf( pErr, "\t-l : toggle sweeping latches [default = %s]\n", fLatchSweep? "yes": "no" ); fprintf( pErr, "\t-l : toggle sweeping latches [default = %s]\n", fLatchSweep? "yes": "no" );
fprintf( pErr, "\t-a : toggle removing autonomous logic [default = %s]\n", fAutoSweep? "yes": "no" ); // fprintf( pErr, "\t-a : toggle removing autonomous logic [default = %s]\n", fAutoSweep? "yes": "no" );
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n"); fprintf( pErr, "\t-h : print the command usage\n");
return 1; return 1;
...@@ -11291,9 +11401,10 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11291,9 +11401,10 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_Ntk_t * pNtk; Abc_Ntk_t * pNtk;
int c; int c;
int nFrames; int nFrames;
int fInputs; int fXInputs;
int fXState;
int fVerbose; int fVerbose;
extern void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVerbose ); extern void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fXInputs, int fXState, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc); pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc); pOut = Abc_FrameReadOut(pAbc);
...@@ -11301,10 +11412,11 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11301,10 +11412,11 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults // set defaults
nFrames = 10; nFrames = 10;
fInputs = 0; fXInputs = 0;
fXState = 0;
fVerbose = 0; fVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Fivh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "Fisvh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -11320,7 +11432,10 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11320,7 +11432,10 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
goto usage; goto usage;
break; break;
case 'i': case 'i':
fInputs ^= 1; fXInputs ^= 1;
break;
case 's':
fXState ^= 1;
break; break;
case 'v': case 'v':
fVerbose ^= 1; fVerbose ^= 1;
...@@ -11343,14 +11458,15 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11343,14 +11458,15 @@ int Abc_CommandXsim( Abc_Frame_t * pAbc, int argc, char ** argv )
return 1; return 1;
} }
Abc_NtkXValueSimulate( pNtk, nFrames, fInputs, fVerbose ); Abc_NtkXValueSimulate( pNtk, nFrames, fXInputs, fXState, fVerbose );
return 0; return 0;
usage: usage:
fprintf( pErr, "usage: xsim [-F num] [-ivh]\n" ); fprintf( pErr, "usage: xsim [-F num] [-isvh]\n" );
fprintf( pErr, "\t performs X-valued simulation of the AIG\n" ); fprintf( pErr, "\t performs X-valued simulation of the AIG\n" );
fprintf( pErr, "\t-F num : the number of frames to simulate [default = %d]\n", nFrames ); fprintf( pErr, "\t-F num : the number of frames to simulate [default = %d]\n", nFrames );
fprintf( pErr, "\t-i : toggle X-valued state or X-valued inputs [default = %s]\n", fInputs? "inputs": "state" ); fprintf( pErr, "\t-i : toggle X-valued representation of inputs [default = %s]\n", fXInputs? "yes": "no" );
fprintf( pErr, "\t-s : toggle X-valued representation of state [default = %s]\n", fXState? "yes": "no" );
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n"); fprintf( pErr, "\t-h : print the command usage\n");
return 1; return 1;
...@@ -11674,11 +11790,12 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11674,11 +11790,12 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv )
char ** pArgvNew; char ** pArgvNew;
int nArgcNew; int nArgcNew;
int c; int c;
int fRetimeFirst;
int fVerbose; int fVerbose;
int fVeryVerbose; int fVeryVerbose;
int nFrames; int nFrames;
extern int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbose, int fVeryVerbose ); extern int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose );
pNtk = Abc_FrameReadNtk(pAbc); pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc); pOut = Abc_FrameReadOut(pAbc);
...@@ -11686,10 +11803,11 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11686,10 +11803,11 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults // set defaults
nFrames = 0; // if 0, iterates through frames nFrames = 0; // if 0, iterates through frames
fVerbose = 1; fRetimeFirst = 1;
fVerbose = 0;
fVeryVerbose = 0; fVeryVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Fwvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "Frwvh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -11704,6 +11822,9 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11704,6 +11822,9 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( nFrames <= 0 ) if ( nFrames <= 0 )
goto usage; goto usage;
break; break;
case 'r':
fRetimeFirst ^= 1;
break;
case 'w': case 'w':
fVeryVerbose ^= 1; fVeryVerbose ^= 1;
break; break;
...@@ -11727,18 +11848,19 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11727,18 +11848,19 @@ int Abc_CommandDSec( Abc_Frame_t * pAbc, int argc, char ** argv )
} }
// perform verification // perform verification
Abc_NtkDarSec( pNtk1, pNtk2, nFrames, fVerbose, fVeryVerbose ); Abc_NtkDarSec( pNtk1, pNtk2, nFrames, fRetimeFirst, fVerbose, fVeryVerbose );
if ( fDelete1 ) Abc_NtkDelete( pNtk1 ); if ( fDelete1 ) Abc_NtkDelete( pNtk1 );
if ( fDelete2 ) Abc_NtkDelete( pNtk2 ); if ( fDelete2 ) Abc_NtkDelete( pNtk2 );
return 0; return 0;
usage: usage:
fprintf( pErr, "usage: dsec [-F num] [-wvh] <file1> <file2>\n" ); fprintf( pErr, "usage: dsec [-F num] [-rwvh] <file1> <file2>\n" );
fprintf( pErr, "\t performs inductive sequential equivalence checking\n" ); fprintf( pErr, "\t performs inductive sequential equivalence checking\n" );
fprintf( pErr, "\t-F num : the number of time frames to use [default = %d]\n", nFrames ); fprintf( pErr, "\t-F num : the number of time frames to use [default = %d]\n", nFrames );
fprintf( pErr, "\t-w : toggles additional verbose output [default = %s]\n", fVeryVerbose? "yes": "no" ); fprintf( pErr, "\t-r : toggles forward retiming at the beginning [default = %s]\n", fRetimeFirst? "yes": "no" );
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-w : toggles additional verbose output [default = %s]\n", fVeryVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n"); fprintf( pErr, "\t-h : print the command usage\n");
fprintf( pErr, "\tfile1 : (optional) the file with the first network\n"); fprintf( pErr, "\tfile1 : (optional) the file with the first network\n");
fprintf( pErr, "\tfile2 : (optional) the file with the second network\n"); fprintf( pErr, "\tfile2 : (optional) the file with the second network\n");
...@@ -11746,6 +11868,95 @@ usage: ...@@ -11746,6 +11868,95 @@ usage:
fprintf( pErr, "\t if one file is given, uses the current network and the file\n"); fprintf( pErr, "\t if one file is given, uses the current network and the file\n");
return 1; return 1;
} }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_CommandDProve( Abc_Frame_t * pAbc, int argc, char ** argv )
{
FILE * pOut, * pErr;
Abc_Ntk_t * pNtk;
int c;
int fRetimeFirst;
int fVerbose;
int fVeryVerbose;
int nFrames;
extern int Abc_NtkDarProve( Abc_Ntk_t * pNtk, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose );
pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc);
pErr = Abc_FrameReadErr(pAbc);
// set defaults
nFrames = 0; // if 0, iterates through frames
fRetimeFirst = 1;
fVerbose = 0;
fVeryVerbose = 0;
Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "Frwvh" ) ) != EOF )
{
switch ( c )
{
case 'F':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-F\" should be followed by an integer.\n" );
goto usage;
}
nFrames = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( nFrames <= 0 )
goto usage;
break;
case 'r':
fRetimeFirst ^= 1;
break;
case 'w':
fVeryVerbose ^= 1;
break;
case 'v':
fVerbose ^= 1;
break;
default:
goto usage;
}
}
if ( Abc_NtkLatchNum(pNtk) == 0 )
{
printf( "The network has no latches. Used combinational command \"iprove\".\n" );
return 0;
}
if ( !Abc_NtkIsStrash(pNtk) )
{
printf( "This command works only for structrally hashed networks. Run \"st\".\n" );
return 0;
}
// perform verification
Abc_NtkDarProve( pNtk, nFrames, fRetimeFirst, fVerbose, fVeryVerbose );
return 0;
usage:
fprintf( pErr, "usage: dprove [-F num] [-rwvh]\n" );
fprintf( pErr, "\t performs SEC on the sequential miter\n" );
fprintf( pErr, "\t-F num : the number of time frames to use [default = %d]\n", nFrames );
fprintf( pErr, "\t-r : toggles forward retiming at the beginning [default = %s]\n", fRetimeFirst? "yes": "no" );
fprintf( pErr, "\t-v : toggles verbose output [default = %s]\n", fVerbose? "yes": "no" );
fprintf( pErr, "\t-w : toggles additional verbose output [default = %s]\n", fVeryVerbose? "yes": "no" );
fprintf( pErr, "\t-h : print the command usage\n");
return 1;
}
/**Function************************************************************* /**Function*************************************************************
Synopsis [] Synopsis []
......
...@@ -122,6 +122,7 @@ Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ) ...@@ -122,6 +122,7 @@ Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan )
{ {
Vec_Ptr_t * vNodes; Vec_Ptr_t * vNodes;
Abc_Ntk_t * pNtkNew; Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObjNew;
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
int i; int i;
assert( Aig_ManRegNum(pMan) == Abc_NtkLatchNum(pNtkOld) ); assert( Aig_ManRegNum(pMan) == Abc_NtkLatchNum(pNtkOld) );
...@@ -141,7 +142,19 @@ Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ) ...@@ -141,7 +142,19 @@ Abc_Ntk_t * Abc_NtkFromDar( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan )
Vec_PtrFree( vNodes ); Vec_PtrFree( vNodes );
// connect the PO nodes // connect the PO nodes
Aig_ManForEachPo( pMan, pObj, i ) Aig_ManForEachPo( pMan, pObj, i )
{
if ( pMan->nAsserts && i == Aig_ManPoNum(pMan) - pMan->nAsserts )
break;
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) ); Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) );
}
// if there are assertions, add them
if ( pMan->nAsserts > 0 )
Aig_ManForEachAssert( pMan, pObj, i )
{
pObjNew = Abc_NtkCreateAssert(pNtkNew);
Abc_ObjAssignName( pObjNew, "assert_", Abc_ObjName(pObjNew) );
Abc_ObjAddFanin( pObjNew, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) );
}
if ( !Abc_NtkCheck( pNtkNew ) ) if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkFromDar(): Network check has failed.\n" ); fprintf( stdout, "Abc_NtkFromDar(): Network check has failed.\n" );
return pNtkNew; return pNtkNew;
...@@ -194,7 +207,19 @@ Abc_Ntk_t * Abc_NtkFromDarSeqSweep( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan ) ...@@ -194,7 +207,19 @@ Abc_Ntk_t * Abc_NtkFromDarSeqSweep( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan )
Vec_PtrFree( vNodes ); Vec_PtrFree( vNodes );
// connect the PO nodes // connect the PO nodes
Aig_ManForEachPo( pMan, pObj, i ) Aig_ManForEachPo( pMan, pObj, i )
{
if ( pMan->nAsserts && i == Aig_ManPoNum(pMan) - pMan->nAsserts )
break;
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) ); Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) );
}
// if there are assertions, add them
if ( pMan->nAsserts > 0 )
Aig_ManForEachAssert( pMan, pObj, i )
{
pObjNew = Abc_NtkCreateAssert(pNtkNew);
Abc_ObjAssignName( pObjNew, "assert_", Abc_ObjName(pObjNew) );
Abc_ObjAddFanin( pObjNew, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj) );
}
if ( !Abc_NtkCheck( pNtkNew ) ) if ( !Abc_NtkCheck( pNtkNew ) )
fprintf( stdout, "Abc_NtkFromDar(): Network check has failed.\n" ); fprintf( stdout, "Abc_NtkFromDar(): Network check has failed.\n" );
return pNtkNew; return pNtkNew;
...@@ -892,7 +917,7 @@ int Abc_NtkDSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fVer ...@@ -892,7 +917,7 @@ int Abc_NtkDSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fVer
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Abc_Ntk_t * Abc_NtkDarSeqSweep( Abc_Ntk_t * pNtk, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose ) Abc_Ntk_t * Abc_NtkDarSeqSweep( Abc_Ntk_t * pNtk, int nFramesP, int nFramesK, int nMaxImps, int fRewrite, int fUseImps, int fLatchCorr, int fWriteImps, int fVerbose )
{ {
Fraig_Params_t Params; Fraig_Params_t Params;
Abc_Ntk_t * pNtkAig, * pNtkFraig; Abc_Ntk_t * pNtkAig, * pNtkFraig;
...@@ -916,7 +941,7 @@ PRT( "Initial fraiging time", clock() - clk ); ...@@ -916,7 +941,7 @@ PRT( "Initial fraiging time", clock() - clk );
if ( pMan == NULL ) if ( pMan == NULL )
return NULL; return NULL;
pMan = Fra_FraigInduction( pTemp = pMan, nFramesP, nFramesK, nMaxImps, fRewrite, fUseImps, fLatchCorr, fVerbose, NULL ); pMan = Fra_FraigInduction( pTemp = pMan, nFramesP, nFramesK, nMaxImps, fRewrite, fUseImps, fLatchCorr, fWriteImps, fVerbose, NULL );
Aig_ManStop( pTemp ); Aig_ManStop( pTemp );
if ( Aig_ManRegNum(pMan) < Abc_NtkLatchNum(pNtk) ) if ( Aig_ManRegNum(pMan) < Abc_NtkLatchNum(pNtk) )
...@@ -929,6 +954,34 @@ PRT( "Initial fraiging time", clock() - clk ); ...@@ -929,6 +954,34 @@ PRT( "Initial fraiging time", clock() - clk );
/**Function************************************************************* /**Function*************************************************************
Synopsis [Computes latch correspondence.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkDarLcorr( Abc_Ntk_t * pNtk, int nFramesP, int nConfMax, int fVerbose )
{
Aig_Man_t * pMan, * pTemp;
Abc_Ntk_t * pNtkAig;
pMan = Abc_NtkToDar( pNtk, 1 );
if ( pMan == NULL )
return NULL;
pMan = Fra_FraigLatchCorrespondence( pTemp = pMan, nFramesP, nConfMax, fVerbose, NULL );
Aig_ManStop( pTemp );
if ( Aig_ManRegNum(pMan) < Abc_NtkLatchNum(pNtk) )
pNtkAig = Abc_NtkFromDarSeqSweep( pNtk, pMan );
else
pNtkAig = Abc_NtkFromDar( pNtk, pMan );
Aig_ManStop( pMan );
return pNtkAig;
}
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.] Synopsis [Gives the current ABC network to AIG manager for processing.]
Description [] Description []
...@@ -938,11 +991,40 @@ PRT( "Initial fraiging time", clock() - clk ); ...@@ -938,11 +991,40 @@ PRT( "Initial fraiging time", clock() - clk );
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbose, int fVeryVerbose ) int Abc_NtkDarProve( Abc_Ntk_t * pNtk, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose )
{ {
Fraig_Params_t Params;
Aig_Man_t * pMan; Aig_Man_t * pMan;
Abc_Ntk_t * pMiter, * pTemp; int RetValue;
// derive the AIG manager
pMan = Abc_NtkToDar( pNtk, 1 );
if ( pMan == NULL )
{
printf( "Converting miter into AIG has failed.\n" );
return -1;
}
assert( pMan->nRegs > 0 );
// perform verification
RetValue = Fra_FraigSec( pMan, nFrames, fRetimeFirst, fVerbose, fVeryVerbose );
Aig_ManStop( pMan );
return RetValue;
}
/**Function*************************************************************
Synopsis [Gives the current ABC network to AIG manager for processing.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fRetimeFirst, int fVerbose, int fVeryVerbose )
{
// Fraig_Params_t Params;
Aig_Man_t * pMan;
Abc_Ntk_t * pMiter;//, * pTemp;
int RetValue; int RetValue;
// get the miter of the two networks // get the miter of the two networks
...@@ -971,6 +1053,8 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo ...@@ -971,6 +1053,8 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo
return 1; return 1;
} }
// commented out because something became non-inductive
/*
// preprocess the miter by fraiging it // preprocess the miter by fraiging it
// (note that for each functional class, fraiging leaves one representative; // (note that for each functional class, fraiging leaves one representative;
// so fraiging does not reduce the number of functions represented by nodes // so fraiging does not reduce the number of functions represented by nodes
...@@ -978,7 +1062,25 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo ...@@ -978,7 +1062,25 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo
Params.nBTLimit = 100000; Params.nBTLimit = 100000;
pMiter = Abc_NtkFraig( pTemp = pMiter, &Params, 0, 0 ); pMiter = Abc_NtkFraig( pTemp = pMiter, &Params, 0, 0 );
Abc_NtkDelete( pTemp ); Abc_NtkDelete( pTemp );
RetValue = Abc_NtkMiterIsConstant( pMiter );
if ( RetValue == 0 )
{
extern void Abc_NtkVerifyReportErrorSeq( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int * pModel, int nFrames );
printf( "Networks are NOT EQUIVALENT after structural hashing.\n" );
// report the error
pMiter->pModel = Abc_NtkVerifyGetCleanModel( pMiter, nFrames );
Abc_NtkVerifyReportErrorSeq( pNtk1, pNtk2, pMiter->pModel, nFrames );
FREE( pMiter->pModel );
Abc_NtkDelete( pMiter );
return 0;
}
if ( RetValue == 1 )
{
Abc_NtkDelete( pMiter );
printf( "Networks are equivalent after structural hashing.\n" );
return 1;
}
*/
// derive the AIG manager // derive the AIG manager
pMan = Abc_NtkToDar( pMiter, 1 ); pMan = Abc_NtkToDar( pMiter, 1 );
Abc_NtkDelete( pMiter ); Abc_NtkDelete( pMiter );
...@@ -990,7 +1092,7 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo ...@@ -990,7 +1092,7 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo
assert( pMan->nRegs > 0 ); assert( pMan->nRegs > 0 );
// perform verification // perform verification
RetValue = Fra_FraigSec( pMan, nFrames, fVerbose, fVeryVerbose ); RetValue = Fra_FraigSec( pMan, nFrames, fRetimeFirst, fVerbose, fVeryVerbose );
Aig_ManStop( pMan ); Aig_ManStop( pMan );
return RetValue; return RetValue;
} }
...@@ -1006,15 +1108,19 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo ...@@ -1006,15 +1108,19 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Abc_Ntk_t * Abc_NtkDarLatchSweep( Abc_Ntk_t * pNtk, int fVerbose ) Abc_Ntk_t * Abc_NtkDarLatchSweep( Abc_Ntk_t * pNtk, int fLatchSweep, int fVerbose )
{ {
Abc_Ntk_t * pNtkAig; Abc_Ntk_t * pNtkAig;
Aig_Man_t * pMan; Aig_Man_t * pMan;
pMan = Abc_NtkToDar( pNtk, 1 ); pMan = Abc_NtkToDar( pNtk, 1 );
if ( pMan == NULL ) if ( pMan == NULL )
return NULL; return NULL;
pMan = Aig_ManReduceLaches( pMan, fVerbose ); Aig_ManSeqCleanup( pMan );
pMan = Aig_ManConstReduce( pMan, fVerbose ); if ( fLatchSweep )
{
pMan = Aig_ManReduceLaches( pMan, fVerbose );
pMan = Aig_ManConstReduce( pMan, fVerbose );
}
pNtkAig = Abc_NtkFromDarSeqSweep( pNtk, pMan ); pNtkAig = Abc_NtkFromDarSeqSweep( pNtk, pMan );
Aig_ManStop( pMan ); Aig_ManStop( pMan );
return pNtkAig; return pNtkAig;
...@@ -1038,6 +1144,8 @@ Abc_Ntk_t * Abc_NtkDarRetime( Abc_Ntk_t * pNtk, int nStepsMax, int fVerbose ) ...@@ -1038,6 +1144,8 @@ Abc_Ntk_t * Abc_NtkDarRetime( Abc_Ntk_t * pNtk, int nStepsMax, int fVerbose )
pMan = Abc_NtkToDar( pNtk, 1 ); pMan = Abc_NtkToDar( pNtk, 1 );
if ( pMan == NULL ) if ( pMan == NULL )
return NULL; return NULL;
// Aig_ManReduceLachesCount( pMan );
pMan = Rtm_ManRetime( pTemp = pMan, 1, nStepsMax, 0 ); pMan = Rtm_ManRetime( pTemp = pMan, 1, nStepsMax, 0 );
Aig_ManStop( pTemp ); Aig_ManStop( pTemp );
......
...@@ -213,6 +213,9 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored ) ...@@ -213,6 +213,9 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored )
printf( "Total nodes = %6d %6.2f Mb Changes = %6d.\n", printf( "Total nodes = %6d %6.2f Mb Changes = %6d.\n",
s_TotalNodes, s_TotalNodes * 20.0 / (1<<20), s_TotalChanges ); s_TotalNodes, s_TotalNodes * 20.0 / (1<<20), s_TotalChanges );
*/ */
// if ( Abc_NtkHasSop(pNtk) )
// printf( "The total number of cube pairs = %d.\n", Abc_NtkGetCubePairNum(pNtk) );
} }
/**Function************************************************************* /**Function*************************************************************
......
...@@ -233,7 +233,8 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos ) ...@@ -233,7 +233,8 @@ int Abc_NtkAppend( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int fAddPos )
// perform strashing // perform strashing
nNewCis = 0; nNewCis = 0;
Abc_NtkCleanCopy( pNtk2 ); Abc_NtkCleanCopy( pNtk2 );
Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtk1); if ( Abc_NtkIsStrash(pNtk2) )
Abc_AigConst1(pNtk2)->pCopy = Abc_AigConst1(pNtk1);
Abc_NtkForEachCi( pNtk2, pObj, i ) Abc_NtkForEachCi( pNtk2, pObj, i )
{ {
pName = Abc_ObjName(pObj); pName = Abc_ObjName(pObj);
......
...@@ -103,7 +103,7 @@ static inline void Abc_XsimPrint( FILE * pFile, int Value ) ...@@ -103,7 +103,7 @@ static inline void Abc_XsimPrint( FILE * pFile, int Value )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVerbose ) void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fXInputs, int fXState, int fVerbose )
{ {
Abc_Obj_t * pObj; Abc_Obj_t * pObj;
int i, f; int i, f;
...@@ -111,20 +111,26 @@ void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVer ...@@ -111,20 +111,26 @@ void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVer
srand( 0x12341234 ); srand( 0x12341234 );
// start simulation // start simulation
Abc_ObjSetXsim( Abc_AigConst1(pNtk), XVS1 ); Abc_ObjSetXsim( Abc_AigConst1(pNtk), XVS1 );
if ( fInputs ) if ( fXInputs )
{ {
Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkForEachPi( pNtk, pObj, i )
Abc_ObjSetXsim( pObj, XVSX ); Abc_ObjSetXsim( pObj, XVSX );
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_LatchInit(pObj) );
} }
else else
{ {
Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkForEachPi( pNtk, pObj, i )
Abc_ObjSetXsim( pObj, Abc_XsimRand2() ); Abc_ObjSetXsim( pObj, Abc_XsimRand2() );
}
if ( fXState )
{
Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), XVSX ); Abc_ObjSetXsim( Abc_ObjFanout0(pObj), XVSX );
} }
else
{
Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_LatchInit(pObj) );
}
// simulate and print the result // simulate and print the result
fprintf( stdout, "Frame : Inputs : Latches : Outputs\n" ); fprintf( stdout, "Frame : Inputs : Latches : Outputs\n" );
for ( f = 0; f < nFrames; f++ ) for ( f = 0; f < nFrames; f++ )
...@@ -147,14 +153,24 @@ void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVer ...@@ -147,14 +153,24 @@ void Abc_NtkXValueSimulate( Abc_Ntk_t * pNtk, int nFrames, int fInputs, int fVer
fprintf( stdout, " : " ); fprintf( stdout, " : " );
Abc_NtkForEachPo( pNtk, pObj, i ) Abc_NtkForEachPo( pNtk, pObj, i )
Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) ); Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) );
if ( Abc_NtkAssertNum(pNtk) )
{
fprintf( stdout, " : " );
Abc_NtkForEachAssert( pNtk, pObj, i )
Abc_XsimPrint( stdout, Abc_ObjGetXsim(pObj) );
}
fprintf( stdout, "\n" ); fprintf( stdout, "\n" );
// assign input values // assign input values
if ( fInputs ) if ( fXInputs )
{
Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkForEachPi( pNtk, pObj, i )
Abc_ObjSetXsim( pObj, XVSX ); Abc_ObjSetXsim( pObj, XVSX );
}
else else
{
Abc_NtkForEachPi( pNtk, pObj, i ) Abc_NtkForEachPi( pNtk, pObj, i )
Abc_ObjSetXsim( pObj, Abc_XsimRand2() ); Abc_ObjSetXsim( pObj, Abc_XsimRand2() );
}
// transfer the latch values // transfer the latch values
Abc_NtkForEachLatch( pNtk, pObj, i ) Abc_NtkForEachLatch( pNtk, pObj, i )
Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_ObjGetXsim(Abc_ObjFanin0(pObj)) ); Abc_ObjSetXsim( Abc_ObjFanout0(pObj), Abc_ObjGetXsim(Abc_ObjFanin0(pObj)) );
......
...@@ -58,6 +58,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) ...@@ -58,6 +58,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
Fxu_Single * pSingle; Fxu_Single * pSingle;
Fxu_Double * pDouble; Fxu_Double * pDouble;
int Weight1, Weight2, Weight3; int Weight1, Weight2, Weight3;
int Counter = 0;
s_MemoryTotal = 0; s_MemoryTotal = 0;
s_MemoryPeak = 0; s_MemoryPeak = 0;
...@@ -77,7 +78,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) ...@@ -77,7 +78,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
{ {
Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle ); Weight1 = Fxu_HeapSingleReadMaxWeight( p->pHeapSingle );
if ( pData->fVerbose ) if ( pData->fVerbose )
printf( "Best single = %3d.\n", Weight1 ); printf( "Div %5d : Best single = %5d.\r", Counter++, Weight1 );
if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 ) if ( Weight1 > 0 || Weight1 == 0 && pData->fUse0 )
Fxu_UpdateSingle( p ); Fxu_UpdateSingle( p );
else else
...@@ -92,7 +93,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) ...@@ -92,7 +93,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
{ {
Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
if ( pData->fVerbose ) if ( pData->fVerbose )
printf( "Best double = %3d.\n", Weight2 ); printf( "Div %5d : Best double = %5d.\r", Counter++, Weight2 );
if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 ) if ( Weight2 > 0 || Weight2 == 0 && pData->fUse0 )
Fxu_UpdateDouble( p ); Fxu_UpdateDouble( p );
else else
...@@ -109,7 +110,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) ...@@ -109,7 +110,7 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble ); Weight2 = Fxu_HeapDoubleReadMaxWeight( p->pHeapDouble );
if ( pData->fVerbose ) if ( pData->fVerbose )
printf( "Best double = %3d. Best single = %3d.\n", Weight2, Weight1 ); printf( "Div %5d : Best double = %5d. Best single = %5d.\r", Counter++, Weight2, Weight1 );
//Fxu_Select( p, &pSingle, &pDouble ); //Fxu_Select( p, &pSingle, &pDouble );
if ( Weight1 >= Weight2 ) if ( Weight1 >= Weight2 )
...@@ -140,8 +141,8 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) ...@@ -140,8 +141,8 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
// select the best single and double // select the best single and double
Weight3 = Fxu_Select( p, &pSingle, &pDouble ); Weight3 = Fxu_Select( p, &pSingle, &pDouble );
if ( pData->fVerbose ) if ( pData->fVerbose )
printf( "Best double = %3d. Best single = %3d. Best complement = %3d.\n", printf( "Div %5d : Best double = %5d. Best single = %5d. Best complement = %5d.\r",
Weight2, Weight1, Weight3 ); Counter++, Weight2, Weight1, Weight3 );
if ( Weight3 > 0 || Weight3 == 0 && pData->fUse0 ) if ( Weight3 > 0 || Weight3 == 0 && pData->fUse0 )
Fxu_Update( p, pSingle, pDouble ); Fxu_Update( p, pSingle, pDouble );
...@@ -152,7 +153,8 @@ int Fxu_FastExtract( Fxu_Data_t * pData ) ...@@ -152,7 +153,8 @@ int Fxu_FastExtract( Fxu_Data_t * pData )
} }
if ( pData->fVerbose ) if ( pData->fVerbose )
printf( "Total single = %3d. Total double = %3d. Total compl = %3d.\n", p->nDivs1, p->nDivs2, p->nDivs3 ); printf( "Total single = %3d. Total double = %3d. Total compl = %3d. \n",
p->nDivs1, p->nDivs2, p->nDivs3 );
// create the new covers // create the new covers
if ( pData->nNodesNew ) if ( pData->nNodesNew )
......
...@@ -55,7 +55,8 @@ struct FxuDataStruct ...@@ -55,7 +55,8 @@ struct FxuDataStruct
bool fUseCompl; // set to 1 to have complement taken into account bool fUseCompl; // set to 1 to have complement taken into account
bool fVerbose; // set to 1 to have verbose output bool fVerbose; // set to 1 to have verbose output
int nNodesExt; // the number of divisors to extract int nNodesExt; // the number of divisors to extract
int nPairsMax; // the maximum number of cube pairs to consider int nSingleMax; // the max number of single-cube divisors to consider
int nPairsMax; // the max number of double-cube divisors to consider
// the input information // the input information
Vec_Ptr_t * vSops; // the SOPs for each node in the network Vec_Ptr_t * vSops; // the SOPs for each node in the network
Vec_Ptr_t * vFanins; // the fanins of each node in the network Vec_Ptr_t * vFanins; // the fanins of each node in the network
......
...@@ -178,12 +178,26 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) ...@@ -178,12 +178,26 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData )
// consider the case when cube pairs should be preprocessed // consider the case when cube pairs should be preprocessed
// before adding them to the set of divisors // before adding them to the set of divisors
// if ( pData->fVerbose )
// printf( "The total number of cube pairs is %d.\n", nPairsTotal );
if ( nPairsTotal > 10000000 )
{
printf( "The total number of cube pairs of the network is more than 10,000,000.\n" );
printf( "Command \"fx\" takes a long time to run in such cases. It is suggested\n" );
printf( "that the user changes the network by reducing the size of logic node and\n" );
printf( "consequently the number of cube pairs to be processed by this command.\n" );
printf( "One way to achieve this is to run the commands \"st; multi -m -F <num>\"\n" );
printf( "as a proprocessing step, while selecting <num> as approapriate.\n" );
return NULL;
}
if ( nPairsTotal > pData->nPairsMax ) if ( nPairsTotal > pData->nPairsMax )
if ( !Fxu_PreprocessCubePairs( p, pData->vSops, nPairsTotal, pData->nPairsMax ) ) if ( !Fxu_PreprocessCubePairs( p, pData->vSops, nPairsTotal, pData->nPairsMax ) )
return NULL; return NULL;
// if ( pData->fVerbose )
// printf( "Only %d best cube pairs will be used by the fast extract command.\n", pData->nPairsMax );
// add the var pairs to the heap // add the var pairs to the heap
Fxu_MatrixComputeSingles( p ); Fxu_MatrixComputeSingles( p, pData->fUse0, pData->nSingleMax );
// print stats // print stats
if ( pData->fVerbose ) if ( pData->fVerbose )
...@@ -194,9 +208,8 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData ) ...@@ -194,9 +208,8 @@ Fxu_Matrix * Fxu_CreateMatrix( Fxu_Data_t * pData )
p->lVars.nItems, p->lCubes.nItems ); p->lVars.nItems, p->lCubes.nItems );
fprintf( stdout, "Lits = %d Density = %.5f%%\n", fprintf( stdout, "Lits = %d Density = %.5f%%\n",
p->nEntries, Density ); p->nEntries, Density );
fprintf( stdout, "1-cube divisors = %6d. ", p->lSingles.nItems ); fprintf( stdout, "1-cube divs = %6d. (Total = %6d) ", p->lSingles.nItems, p->nSingleTotal );
fprintf( stdout, "2-cube divisors = %6d. ", p->nDivsTotal ); fprintf( stdout, "2-cube divs = %6d. (Total = %6d)", p->nDivsTotal, nPairsTotal );
fprintf( stdout, "Cube pairs = %6d.", nPairsTotal );
fprintf( stdout, "\n" ); fprintf( stdout, "\n" );
} }
// Fxu_MatrixPrint( stdout, p ); // Fxu_MatrixPrint( stdout, p );
......
...@@ -172,6 +172,8 @@ struct FxuMatrix // ~ 30 words ...@@ -172,6 +172,8 @@ struct FxuMatrix // ~ 30 words
// the single cube divisors // the single cube divisors
Fxu_ListSingle lSingles; // the linked list of single cube divisors Fxu_ListSingle lSingles; // the linked list of single cube divisors
Fxu_HeapSingle * pHeapSingle; // the heap of variables by the number of literals in the matrix Fxu_HeapSingle * pHeapSingle; // the heap of variables by the number of literals in the matrix
int nWeightLimit;// the limit on weight of single cube divisors collected
int nSingleTotal;// the total number of single cube divisors
// storage for cube pairs // storage for cube pairs
Fxu_Pair *** pppPairs; Fxu_Pair *** pppPairs;
Fxu_Pair ** ppPairs; Fxu_Pair ** ppPairs;
...@@ -459,7 +461,7 @@ extern void Fxu_PairClearStorage( Fxu_Cube * pCube ); ...@@ -459,7 +461,7 @@ extern void Fxu_PairClearStorage( Fxu_Cube * pCube );
extern Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 ); extern Fxu_Pair * Fxu_PairAlloc( Fxu_Matrix * p, Fxu_Cube * pCube1, Fxu_Cube * pCube2 );
extern void Fxu_PairAdd( Fxu_Pair * pPair ); extern void Fxu_PairAdd( Fxu_Pair * pPair );
/*===== fxuSingle.c ====================================================*/ /*===== fxuSingle.c ====================================================*/
extern void Fxu_MatrixComputeSingles( Fxu_Matrix * p ); extern void Fxu_MatrixComputeSingles( Fxu_Matrix * p, int fUse0, int nSingleMax );
extern void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ); extern void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar );
extern int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 ); extern int Fxu_SingleCountCoincidence( Fxu_Matrix * p, Fxu_Var * pVar1, Fxu_Var * pVar2 );
/*===== fxuMatrix.c ====================================================*/ /*===== fxuMatrix.c ====================================================*/
......
...@@ -17,11 +17,14 @@ ...@@ -17,11 +17,14 @@
***********************************************************************/ ***********************************************************************/
#include "fxuInt.h" #include "fxuInt.h"
#include "vec.h"
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
static void Fxu_MatrixComputeSinglesOneCollect( Fxu_Matrix * p, Fxu_Var * pVar, Vec_Ptr_t * vSingles );
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS /// /// FUNCTION DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -38,12 +41,130 @@ ...@@ -38,12 +41,130 @@
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fxu_MatrixComputeSingles( Fxu_Matrix * p ) void Fxu_MatrixComputeSingles( Fxu_Matrix * p, int fUse0, int nSingleMax )
{ {
Fxu_Var * pVar; Fxu_Var * pVar;
// iterate through the columns in the matrix Vec_Ptr_t * vSingles;
int i, k;
// set the weight limit
p->nWeightLimit = 1 - fUse0;
// iterate through columns in the matrix and collect single-cube divisors
vSingles = Vec_PtrAlloc( 10000 );
Fxu_MatrixForEachVariable( p, pVar ) Fxu_MatrixForEachVariable( p, pVar )
Fxu_MatrixComputeSinglesOne( p, pVar ); Fxu_MatrixComputeSinglesOneCollect( p, pVar, vSingles );
p->nSingleTotal = Vec_PtrSize(vSingles) / 3;
// check if divisors should be filtered
if ( Vec_PtrSize(vSingles) > nSingleMax )
{
int * pWeigtCounts, nDivCount, Weight, i, c;;
assert( Vec_PtrSize(vSingles) % 3 == 0 );
// count how many divisors have the given weight
pWeigtCounts = ALLOC( int, 1000 );
memset( pWeigtCounts, 0, sizeof(int) * 1000 );
for ( i = 2; i < Vec_PtrSize(vSingles); i += 3 )
{
Weight = (int)Vec_PtrEntry(vSingles, i);
if ( Weight >= 999 )
pWeigtCounts[999]++;
else
pWeigtCounts[Weight]++;
}
// select the bound on the weight (above this bound, singles will be included)
nDivCount = 0;
for ( c = 999; c >= 0; c-- )
{
nDivCount += pWeigtCounts[c];
if ( nDivCount >= nSingleMax )
break;
}
free( pWeigtCounts );
// collect singles with the given costs
k = 0;
for ( i = 2; i < Vec_PtrSize(vSingles); i += 3 )
{
Weight = (int)Vec_PtrEntry(vSingles, i);
if ( Weight < c )
continue;
Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i-2) );
Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i-1) );
Vec_PtrWriteEntry( vSingles, k++, Vec_PtrEntry(vSingles, i) );
if ( k/3 == nSingleMax )
break;
}
Vec_PtrShrink( vSingles, k );
// adjust the weight limit
p->nWeightLimit = c;
}
// collect the selected divisors
assert( Vec_PtrSize(vSingles) % 3 == 0 );
for ( i = 0; i < Vec_PtrSize(vSingles); i += 3 )
{
Fxu_MatrixAddSingle( p,
Vec_PtrEntry(vSingles,i),
Vec_PtrEntry(vSingles,i+1),
(int)Vec_PtrEntry(vSingles,i+2) );
}
Vec_PtrFree( vSingles );
}
/**Function*************************************************************
Synopsis [Adds the single-cube divisors associated with a new column.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fxu_MatrixComputeSinglesOneCollect( Fxu_Matrix * p, Fxu_Var * pVar, Vec_Ptr_t * vSingles )
{
Fxu_Lit * pLitV, * pLitH;
Fxu_Var * pVar2;
int Coin;
int WeightCur;
// start collecting the affected vars
Fxu_MatrixRingVarsStart( p );
// go through all the literals of this variable
for ( pLitV = pVar->lLits.pHead; pLitV; pLitV = pLitV->pVNext )
// for this literal, go through all the horizontal literals
for ( pLitH = pLitV->pHPrev; pLitH; pLitH = pLitH->pHPrev )
{
// get another variable
pVar2 = pLitH->pVar;
// skip the var if it is already used
if ( pVar2->pOrder )
continue;
// skip the var if it belongs to the same node
// if ( pValue2Node[pVar->iVar] == pValue2Node[pVar2->iVar] )
// continue;
// collect the var
Fxu_MatrixRingVarsAdd( p, pVar2 );
}
// stop collecting the selected vars
Fxu_MatrixRingVarsStop( p );
// iterate through the selected vars
Fxu_MatrixForEachVarInRing( p, pVar2 )
{
// count the coincidence
Coin = Fxu_SingleCountCoincidence( p, pVar2, pVar );
assert( Coin > 0 );
// get the new weight
WeightCur = Coin - 2;
// peformance fix (August 24, 2007)
if ( WeightCur >= p->nWeightLimit )
{
Vec_PtrPush( vSingles, pVar2 );
Vec_PtrPush( vSingles, pVar );
Vec_PtrPush( vSingles, (void *)WeightCur );
}
}
// unmark the vars
Fxu_MatrixRingVarsUnmark( p );
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -59,12 +180,9 @@ void Fxu_MatrixComputeSingles( Fxu_Matrix * p ) ...@@ -59,12 +180,9 @@ void Fxu_MatrixComputeSingles( Fxu_Matrix * p )
***********************************************************************/ ***********************************************************************/
void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ) void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar )
{ {
// int * pValue2Node = p->pValue2Node;
Fxu_Lit * pLitV, * pLitH; Fxu_Lit * pLitV, * pLitH;
Fxu_Var * pVar2; Fxu_Var * pVar2;
int Coin; int Coin;
// int CounterAll;
// int CounterTest;
int WeightCur; int WeightCur;
// start collecting the affected vars // start collecting the affected vars
...@@ -76,7 +194,6 @@ void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ) ...@@ -76,7 +194,6 @@ void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar )
{ {
// get another variable // get another variable
pVar2 = pLitH->pVar; pVar2 = pLitH->pVar;
// CounterAll++;
// skip the var if it is already used // skip the var if it is already used
if ( pVar2->pOrder ) if ( pVar2->pOrder )
continue; continue;
...@@ -92,16 +209,17 @@ void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar ) ...@@ -92,16 +209,17 @@ void Fxu_MatrixComputeSinglesOne( Fxu_Matrix * p, Fxu_Var * pVar )
// iterate through the selected vars // iterate through the selected vars
Fxu_MatrixForEachVarInRing( p, pVar2 ) Fxu_MatrixForEachVarInRing( p, pVar2 )
{ {
// CounterTest++;
// count the coincidence // count the coincidence
Coin = Fxu_SingleCountCoincidence( p, pVar2, pVar ); Coin = Fxu_SingleCountCoincidence( p, pVar2, pVar );
assert( Coin > 0 ); assert( Coin > 0 );
// get the new weight // get the new weight
WeightCur = Coin - 2; WeightCur = Coin - 2;
if ( WeightCur >= 0 ) // peformance fix (August 24, 2007)
// if ( WeightCur >= 0 )
// Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur );
if ( WeightCur >= p->nWeightLimit )
Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur ); Fxu_MatrixAddSingle( p, pVar2, pVar, WeightCur );
} }
// unmark the vars // unmark the vars
Fxu_MatrixRingVarsUnmark( p ); Fxu_MatrixRingVarsUnmark( p );
} }
......
...@@ -757,12 +757,14 @@ void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p ) ...@@ -757,12 +757,14 @@ void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p )
{ {
Fxu_Single * pSingle, * pSingle2; Fxu_Single * pSingle, * pSingle2;
int WeightNew; int WeightNew;
int Counter = 0;
Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 ) Fxu_MatrixForEachSingleSafe( p, pSingle, pSingle2 )
{ {
// if at least one of the variables is marked, recalculate // if at least one of the variables is marked, recalculate
if ( pSingle->pVar1->pOrder || pSingle->pVar2->pOrder ) if ( pSingle->pVar1->pOrder || pSingle->pVar2->pOrder )
{ {
Counter++;
// get the new weight // get the new weight
WeightNew = -2 + Fxu_SingleCountCoincidence( p, pSingle->pVar1, pSingle->pVar2 ); WeightNew = -2 + Fxu_SingleCountCoincidence( p, pSingle->pVar1, pSingle->pVar2 );
if ( WeightNew >= 0 ) if ( WeightNew >= 0 )
...@@ -778,6 +780,7 @@ void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p ) ...@@ -778,6 +780,7 @@ void Fxu_UpdateCleanOldSingles( Fxu_Matrix * p )
} }
} }
} }
// printf( "Called procedure %d times.\n", Counter );
} }
/**Function************************************************************* /**Function*************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment