Commit 3244fa2f by Alan Mishchenko

Version abc70818

parent 9e4213e2
...@@ -49,8 +49,9 @@ extern "C" { ...@@ -49,8 +49,9 @@ extern "C" {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
typedef struct Fra_Par_t_ Fra_Par_t; typedef struct Fra_Par_t_ Fra_Par_t;
typedef struct Fra_Cla_t_ Fra_Cla_t;
typedef struct Fra_Man_t_ Fra_Man_t; typedef struct Fra_Man_t_ Fra_Man_t;
typedef struct Fra_Cla_t_ Fra_Cla_t;
typedef struct Fra_Sml_t_ Fra_Sml_t;
// FRAIG parameters // FRAIG parameters
struct Fra_Par_t_ struct Fra_Par_t_
...@@ -72,6 +73,7 @@ struct Fra_Par_t_ ...@@ -72,6 +73,7 @@ struct Fra_Par_t_
int nFramesK; // the number of timeframes to unroll int nFramesK; // the number of timeframes to unroll
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
}; };
// FRAIG equivalence classes // FRAIG equivalence classes
...@@ -88,6 +90,19 @@ struct Fra_Cla_t_ ...@@ -88,6 +90,19 @@ struct Fra_Cla_t_
Vec_Ptr_t * vClassNew; // new equivalence class(es) after splitting Vec_Ptr_t * vClassNew; // new equivalence class(es) after splitting
int nPairs; // the number of pairs of nodes int nPairs; // the number of pairs of nodes
int fRefinement; // set to 1 when refinement has happened int fRefinement; // set to 1 when refinement has happened
Vec_Int_t * vImps; // implications
};
// simulation manager
struct Fra_Sml_t_
{
Aig_Man_t * pAig; // the original AIG manager
int nFrames; // the number of times frames
int nWordsFrame; // the number of words in each time frame
int nWordsTotal; // the total number of words at a node
int nSimRounds; // statistics
int timeSim; // statistics
unsigned pData[0]; // simulation data for the nodes
}; };
// FRAIG manager // FRAIG manager
...@@ -101,17 +116,14 @@ struct Fra_Man_t_ ...@@ -101,17 +116,14 @@ struct Fra_Man_t_
// mapping AIG into FRAIG // mapping AIG into FRAIG
int nFramesAll; // the number of timeframes used int nFramesAll; // the number of timeframes used
Aig_Obj_t ** pMemFraig; // memory allocated for points to the fraig nodes Aig_Obj_t ** pMemFraig; // memory allocated for points to the fraig nodes
// equivalence classes
Fra_Cla_t * pCla; // representation of (candidate) equivalent nodes
// simulation info // simulation info
void * pSim; // the simulation manager Fra_Sml_t * pSml; // simulation manager
unsigned * pSimWords; // memory for simulation information
int nSimWords; // the number of simulation words
// counter example storage // counter example storage
int nPatWords; // the number of words in the counter example int nPatWords; // the number of words in the counter example
unsigned * pPatWords; // the counter example unsigned * pPatWords; // the counter example
int * pPatScores; // the scores of each pattern // satisfiability solving
// equivalence classes
Fra_Cla_t * pCla; // representation of (candidate) equivalent nodes
// equivalence checking
sat_solver * pSat; // SAT solver sat_solver * pSat; // SAT solver
int nSatVars; // the number of variables currently used int nSatVars; // the number of variables currently used
Vec_Ptr_t * vPiVars; // the PIs of the cone used Vec_Ptr_t * vPiVars; // the PIs of the cone used
...@@ -140,6 +152,8 @@ struct Fra_Man_t_ ...@@ -140,6 +152,8 @@ struct Fra_Man_t_
int nSpeculs; int nSpeculs;
int nChoices; int nChoices;
int nChoicesFake; int nChoicesFake;
int nSatCallsRecent;
int nSatCallsSkipped;
// runtime // runtime
int timeSim; int timeSim;
int timeTrav; int timeTrav;
...@@ -158,7 +172,7 @@ struct Fra_Man_t_ ...@@ -158,7 +172,7 @@ struct Fra_Man_t_
/// MACRO DEFINITIONS /// /// MACRO DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
static inline unsigned * Fra_ObjSim( Aig_Obj_t * pObj ) { return ((Fra_Man_t *)pObj->pData)->pSimWords + ((Fra_Man_t *)pObj->pData)->nSimWords * pObj->Id; } static inline unsigned * Fra_ObjSim( Fra_Sml_t * p, int Id ) { return p->pData + p->nWordsTotal * Id; }
static inline unsigned Fra_ObjRandomSim() { return (rand() << 24) ^ (rand() << 12) ^ rand(); } static inline unsigned Fra_ObjRandomSim() { return (rand() << 24) ^ (rand() << 12) ^ rand(); }
static inline Aig_Obj_t * Fra_ObjFraig( Aig_Obj_t * pObj, int i ) { return ((Fra_Man_t *)pObj->pData)->pMemFraig[((Fra_Man_t *)pObj->pData)->nFramesAll*pObj->Id + i]; } static inline Aig_Obj_t * Fra_ObjFraig( Aig_Obj_t * pObj, int i ) { return ((Fra_Man_t *)pObj->pData)->pMemFraig[((Fra_Man_t *)pObj->pData)->nFramesAll*pObj->Id + i]; }
...@@ -196,6 +210,7 @@ extern int Fra_ClassesCountLits( Fra_Cla_t * p ); ...@@ -196,6 +210,7 @@ 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 );
extern void Fra_ClassesLatchCorr( Fra_Man_t * p ); extern void Fra_ClassesLatchCorr( Fra_Man_t * p );
extern void Fra_ClassesPostprocess( Fra_Cla_t * p );
/*=== fraCnf.c ========================================================*/ /*=== fraCnf.c ========================================================*/
extern void Fra_NodeAddToSolver( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ); extern void Fra_NodeAddToSolver( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
/*=== fraCore.c ========================================================*/ /*=== fraCore.c ========================================================*/
...@@ -203,9 +218,14 @@ extern Aig_Man_t * Fra_FraigPerform( Aig_Man_t * pManAig, Fra_Par_t * pP ...@@ -203,9 +218,14 @@ extern Aig_Man_t * Fra_FraigPerform( Aig_Man_t * pManAig, Fra_Par_t * pP
extern Aig_Man_t * Fra_FraigChoice( Aig_Man_t * pManAig ); 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 );
/*=== fraDfs.c ========================================================*/ /*=== fraImp.c ========================================================*/
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 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 void Fra_ImpCompactArray( Vec_Int_t * vImps );
/*=== fraInd.c ========================================================*/ /*=== fraInd.c ========================================================*/
extern Aig_Man_t * Fra_FraigInduction( Aig_Man_t * p, int nFramesK, int fRewrite, int fLatchCorr, int fVerbose, int * pnIter ); extern Aig_Man_t * Fra_FraigInduction( Aig_Man_t * p, int nFramesK, int fRewrite, int fUseImps, int fLatchCorr, 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 );
...@@ -217,6 +237,7 @@ extern void Fra_ManStop( Fra_Man_t * p ); ...@@ -217,6 +237,7 @@ extern void Fra_ManStop( Fra_Man_t * p );
extern void Fra_ManPrint( Fra_Man_t * p ); extern void Fra_ManPrint( Fra_Man_t * p );
/*=== fraSat.c ========================================================*/ /*=== fraSat.c ========================================================*/
extern int Fra_NodesAreEquiv( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ); extern int Fra_NodesAreEquiv( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
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 fVerbose, int fVeryVerbose );
...@@ -224,10 +245,15 @@ extern int Fra_FraigSec( Aig_Man_t * p, int nFrames, int fVerbos ...@@ -224,10 +245,15 @@ extern int Fra_FraigSec( Aig_Man_t * p, int nFrames, int fVerbos
extern int Fra_NodeHasZeroSim( Aig_Obj_t * pObj ); extern int Fra_NodeHasZeroSim( Aig_Obj_t * pObj );
extern int Fra_NodeCompareSims( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ); extern int Fra_NodeCompareSims( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
extern unsigned Fra_NodeHashSims( Aig_Obj_t * pObj ); extern unsigned Fra_NodeHashSims( Aig_Obj_t * pObj );
extern void Fra_SavePattern( Fra_Man_t * p );
extern void Fra_Simulate( Fra_Man_t * p, int fInit );
extern void Fra_Resimulate( Fra_Man_t * p );
extern int Fra_CheckOutputSims( Fra_Man_t * p ); extern int Fra_CheckOutputSims( Fra_Man_t * p );
extern void Fra_SavePattern( Fra_Man_t * p );
extern void Fra_SmlSimulate( Fra_Man_t * p, int fInit );
extern void Fra_SmlResimulate( Fra_Man_t * p );
extern Fra_Sml_t * Fra_SmlStart( Aig_Man_t * pAig, int nFrames, int nWordsFrame );
extern void Fra_SmlStop( Fra_Sml_t * p );
extern Fra_Sml_t * Fra_SmlSimulateSeq( Aig_Man_t * pAig, int nFrames, int nWords );
extern Fra_Sml_t * Fra_SmlSimulateComb( Aig_Man_t * pAig, int nWords );
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -90,6 +90,7 @@ void Fra_ClassesStop( Fra_Cla_t * p ) ...@@ -90,6 +90,7 @@ void Fra_ClassesStop( Fra_Cla_t * p )
if ( p->vClassOld ) Vec_PtrFree( p->vClassOld ); if ( p->vClassOld ) Vec_PtrFree( p->vClassOld );
if ( p->vClasses1 ) Vec_PtrFree( p->vClasses1 ); if ( p->vClasses1 ) Vec_PtrFree( p->vClasses1 );
if ( p->vClasses ) Vec_PtrFree( p->vClasses ); if ( p->vClasses ) Vec_PtrFree( p->vClasses );
if ( p->vImps ) Vec_IntFree( p->vImps );
free( p ); free( p );
} }
...@@ -597,6 +598,93 @@ void Fra_ClassesLatchCorr( Fra_Man_t * p ) ...@@ -597,6 +598,93 @@ void Fra_ClassesLatchCorr( Fra_Man_t * p )
p->pCla->pMemClassesFree = p->pCla->pMemClasses + 2*nEntries; p->pCla->pMemClassesFree = p->pCla->pMemClasses + 2*nEntries;
} }
/**Function*************************************************************
Synopsis [Counts the number of 1s in the XOR of simulation data.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Fra_SmlNodeNotEquWeight( Fra_Sml_t * p, int Left, int Right )
{
unsigned * pSimL, * pSimR;
int k, Counter = 0;
pSimL = Fra_ObjSim( p, Left );
pSimR = Fra_ObjSim( p, Right );
for ( k = 0; k < p->nWordsTotal; k++ )
Counter += Aig_WordCountOnes( pSimL[k] ^ pSimR[k] );
return Counter;
}
/**Function*************************************************************
Synopsis [Postprocesses the classes by removing half of the less useful.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_ClassesPostprocess( Fra_Cla_t * p )
{
int Ratio = 2;
Fra_Sml_t * pComb;
Aig_Obj_t * pObj, * pRepr, ** ppClass;
int * pWeights, WeightMax = 0, i, k, c;
// perform combinational simulation
pComb = Fra_SmlSimulateComb( p->pAig, 32 );
// compute the weight of each node in the classes
pWeights = ALLOC( int, Aig_ManObjIdMax(p->pAig) + 1 );
memset( pWeights, 0, sizeof(int) * (Aig_ManObjIdMax(p->pAig) + 1) );
Aig_ManForEachObj( p->pAig, pObj, i )
{
pRepr = Fra_ClassObjRepr( pObj );
if ( pRepr == NULL )
continue;
pWeights[i] = Fra_SmlNodeNotEquWeight( pComb, pRepr->Id, pObj->Id );
WeightMax = AIG_MAX( WeightMax, pWeights[i] );
}
Fra_SmlStop( pComb );
printf( "Before: Const = %6d. Class = %6d. ", Vec_PtrSize(p->vClasses1), Vec_PtrSize(p->vClasses) );
// remove nodes from classes whose weight is less than WeightMax/Ratio
k = 0;
Vec_PtrForEachEntry( p->vClasses1, pObj, i )
{
if ( pWeights[pObj->Id] >= WeightMax/Ratio )
Vec_PtrWriteEntry( p->vClasses1, k++, pObj );
else
Fra_ClassObjSetRepr( pObj, NULL );
}
Vec_PtrShrink( p->vClasses1, k );
// in each class, compact the nodes
Vec_PtrForEachEntry( p->vClasses, ppClass, i )
{
k = 1;
for ( c = 1; ppClass[c]; c++ )
{
if ( pWeights[ppClass[c]->Id] >= WeightMax/Ratio )
ppClass[k++] = ppClass[c];
else
Fra_ClassObjSetRepr( ppClass[c], NULL );
}
ppClass[k] = NULL;
}
// remove classes with only repr
k = 0;
Vec_PtrForEachEntry( p->vClasses, ppClass, i )
if ( ppClass[1] != NULL )
Vec_PtrWriteEntry( p->vClasses, k++, ppClass );
Vec_PtrShrink( p->vClasses, k );
printf( "After: Const = %6d. Class = %6d. \n", Vec_PtrSize(p->vClasses1), Vec_PtrSize(p->vClasses) );
free( pWeights );
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -142,7 +142,10 @@ static inline void Fra_FraigNode( Fra_Man_t * p, Aig_Obj_t * pObj ) ...@@ -142,7 +142,10 @@ static inline void Fra_FraigNode( Fra_Man_t * p, Aig_Obj_t * pObj )
pObjReprFraig = Fra_ObjFraig( pObjRepr, p->pPars->nFramesK ); pObjReprFraig = Fra_ObjFraig( pObjRepr, p->pPars->nFramesK );
// if the fraiged nodes are the same, return // if the fraiged nodes are the same, return
if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) ) if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
{
p->nSatCallsSkipped++;
return; return;
}
assert( p->pPars->nFramesK || Aig_Regular(pObjFraig) != Aig_ManConst1(p->pManFraig) ); assert( p->pPars->nFramesK || Aig_Regular(pObjFraig) != Aig_ManConst1(p->pManFraig) );
// if they are proved different, the c-ex will be in p->pPatWords // if they are proved different, the c-ex will be in p->pPatWords
RetValue = Fra_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) ); RetValue = Fra_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
...@@ -177,7 +180,7 @@ static inline void Fra_FraigNode( Fra_Man_t * p, Aig_Obj_t * pObj ) ...@@ -177,7 +180,7 @@ static inline void Fra_FraigNode( Fra_Man_t * p, Aig_Obj_t * pObj )
if ( p->vTimeouts ) if ( p->vTimeouts )
Vec_PtrPush( p->vTimeouts, pObj ); Vec_PtrPush( p->vTimeouts, pObj );
// simulate the counter-example and return the Fraig node // simulate the counter-example and return the Fraig node
Fra_Resimulate( p ); Fra_SmlResimulate( p );
if ( Fra_ClassObjRepr(pObj) == pObjRepr ) if ( Fra_ClassObjRepr(pObj) == pObjRepr )
printf( "Fra_FraigNode(): Error in class refinement!\n" ); printf( "Fra_FraigNode(): Error in class refinement!\n" );
assert( Fra_ClassObjRepr(pObj) != pObjRepr ); assert( Fra_ClassObjRepr(pObj) != pObjRepr );
...@@ -198,13 +201,18 @@ void Fra_FraigSweep( Fra_Man_t * p ) ...@@ -198,13 +201,18 @@ void Fra_FraigSweep( Fra_Man_t * p )
{ {
ProgressBar * pProgress; ProgressBar * pProgress;
Aig_Obj_t * pObj, * pObjNew; Aig_Obj_t * pObj, * pObjNew;
int i, k = 0; int i, k = 0, Pos = 0;
// duplicate internal nodes
pProgress = Extra_ProgressBarStart( stdout, Aig_ManObjIdMax(p->pManAig) );
// fraig latch outputs // fraig latch outputs
Aig_ManForEachLoSeq( p->pManAig, pObj, i ) Aig_ManForEachLoSeq( p->pManAig, pObj, i )
{
Fra_FraigNode( p, pObj ); Fra_FraigNode( p, pObj );
if ( p->pPars->fUseImps )
Pos = Fra_ImpCheckForNode( p, p->pCla->vImps, pObj, Pos );
}
if ( p->pPars->fLatchCorr )
return;
// fraig internal nodes // fraig internal nodes
pProgress = Extra_ProgressBarStart( stdout, Aig_ManObjIdMax(p->pManAig) );
Aig_ManForEachNode( p->pManAig, pObj, i ) Aig_ManForEachNode( p->pManAig, pObj, i )
{ {
Extra_ProgressBarUpdate( pProgress, i, NULL ); Extra_ProgressBarUpdate( pProgress, i, NULL );
...@@ -217,6 +225,8 @@ void Fra_FraigSweep( Fra_Man_t * p ) ...@@ -217,6 +225,8 @@ void Fra_FraigSweep( Fra_Man_t * p )
continue; continue;
// perform fraiging // perform fraiging
Fra_FraigNode( p, pObj ); Fra_FraigNode( p, pObj );
if ( p->pPars->fUseImps )
Pos = Fra_ImpCheckForNode( p, p->pCla->vImps, pObj, Pos );
} }
Extra_ProgressBarStop( pProgress ); Extra_ProgressBarStop( pProgress );
// try to prove the outputs of the miter // try to prove the outputs of the miter
...@@ -224,6 +234,9 @@ void Fra_FraigSweep( Fra_Man_t * p ) ...@@ -224,6 +234,9 @@ void Fra_FraigSweep( Fra_Man_t * p )
// Fra_MiterStatus( p->pManFraig ); // Fra_MiterStatus( p->pManFraig );
// if ( p->pPars->fProve && p->pManFraig->pData == NULL ) // if ( p->pPars->fProve && p->pManFraig->pData == NULL )
// Fra_MiterProve( p ); // Fra_MiterProve( p );
// compress implications after processing all of them
if ( p->pPars->fUseImps )
Fra_ImpCompactArray( p->pCla->vImps );
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -248,7 +261,8 @@ clk = clock(); ...@@ -248,7 +261,8 @@ clk = clock();
assert( Aig_ManLatchNum(pManAig) == 0 ); assert( Aig_ManLatchNum(pManAig) == 0 );
p = Fra_ManStart( pManAig, pPars ); p = Fra_ManStart( pManAig, pPars );
p->pManFraig = Fra_ManPrepareComb( p ); p->pManFraig = Fra_ManPrepareComb( p );
Fra_Simulate( p, 0 ); p->pSml = Fra_SmlStart( pManAig, 1, pPars->nSimWords );
Fra_SmlSimulate( p, 0 );
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
......
...@@ -24,401 +24,16 @@ ...@@ -24,401 +24,16 @@
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// simulation manager
typedef struct Sml_Man_t_ Sml_Man_t;
struct Sml_Man_t_
{
Aig_Man_t * pAig;
int nFrames;
int nWordsFrame;
int nWordsTotal;
unsigned pData[0];
};
static inline unsigned * Sml_ObjSim( Sml_Man_t * p, int Id ) { return p->pData + p->nWordsTotal * Id; }
static inline int Sml_ImpLeft( int Imp ) { return Imp & 0xFFFF; } static inline int Sml_ImpLeft( int Imp ) { return Imp & 0xFFFF; }
static inline int Sml_ImpRight( int Imp ) { return Imp >> 16; } static inline int Sml_ImpRight( int Imp ) { return Imp >> 16; }
static inline int Sml_ImpCreate( int Left, int Right ) { return (Right << 16) | Left; } static inline int Sml_ImpCreate( int Left, int Right ) { return (Right << 16) | Left; }
static int * s_ImpCost = NULL;
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS /// /// FUNCTION DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/**Function************************************************************* /**Function*************************************************************
Synopsis [Allocates simulation manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Sml_Man_t * Sml_ManStart( Aig_Man_t * pAig, int nFrames, int nWordsFrame )
{
Sml_Man_t * p;
assert( Aig_ManObjIdMax(pAig) + 1 < (1 << 16) );
p = (Sml_Man_t *)malloc( sizeof(Sml_Man_t) + sizeof(unsigned) * (Aig_ManObjIdMax(pAig) + 1) * nFrames * nWordsFrame );
memset( p, 0, sizeof(Sml_Man_t) + sizeof(unsigned) * nFrames * nWordsFrame );
p->nFrames = nFrames;
p->nWordsFrame = nWordsFrame;
p->nWordsTotal = nFrames * nWordsFrame;
return p;
}
/**Function*************************************************************
Synopsis [Deallocates simulation manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sml_ManStop( Sml_Man_t * p )
{
free( p );
}
/**Function*************************************************************
Synopsis [Assigns random patterns to the PI node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sml_ManAssignRandom( Sml_Man_t * p, Aig_Obj_t * pObj )
{
unsigned * pSims;
int i;
assert( Aig_ObjIsPi(pObj) );
pSims = Sml_ObjSim( p, pObj->Id );
for ( i = 0; i < p->nWordsTotal; i++ )
pSims[i] = Fra_ObjRandomSim();
}
/**Function*************************************************************
Synopsis [Assigns constant patterns to the PI node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sml_ManAssignConst( Sml_Man_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame )
{
unsigned * pSims;
int i;
assert( Aig_ObjIsPi(pObj) );
pSims = Sml_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = fConst1? ~(unsigned)0 : 0;
}
/**Function*************************************************************
Synopsis [Assings random simulation info for the PIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sml_ManInitialize( Sml_Man_t * p, int fInit )
{
Aig_Obj_t * pObj;
int i;
if ( fInit )
{
assert( Aig_ManRegNum(p->pAig) > 0 );
assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
// assign random info for primary inputs
Aig_ManForEachPiSeq( p->pAig, pObj, i )
Sml_ManAssignRandom( p, pObj );
// assign the initial state for the latches
Aig_ManForEachLoSeq( p->pAig, pObj, i )
Sml_ManAssignConst( p, pObj, 0, 0 );
}
else
{
Aig_ManForEachPi( p->pAig, pObj, i )
Sml_ManAssignRandom( p, pObj );
}
}
/**Function*************************************************************
Synopsis [Assings distance-1 simulation info for the PIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sml_ManAssignDist1( Sml_Man_t * p, unsigned * pPat )
{
Aig_Obj_t * pObj;
int f, i, k, Limit, nTruePis;
assert( p->nFrames > 0 );
if ( p->nFrames == 1 )
{
// copy the PI info
Aig_ManForEachPi( p->pAig, pObj, i )
Sml_ManAssignConst( p, pObj, Aig_InfoHasBit(pPat, i), 0 );
// flip one bit
Limit = AIG_MIN( Aig_ManPiNum(p->pAig), p->nWordsTotal * 32 - 1 );
for ( i = 0; i < Limit; i++ )
Aig_InfoXorBit( Sml_ObjSim( p, Aig_ManPi(p->pAig,i)->Id ), i+1 );
}
else
{
// copy the PI info for each frame
nTruePis = Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig);
for ( f = 0; f < p->nFrames; f++ )
Aig_ManForEachPiSeq( p->pAig, pObj, i )
Sml_ManAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * f + i), f );
// copy the latch info
k = 0;
Aig_ManForEachLoSeq( p->pAig, pObj, i )
Sml_ManAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * p->nFrames + k++), 0 );
// assert( p->pManFraig == NULL || nTruePis * p->nFrames + k == Aig_ManPiNum(p->pManFraig) );
// flip one bit of the last frame
if ( p->nFrames == 2 )
{
Limit = AIG_MIN( nTruePis, p->nWordsFrame * 32 - 1 );
for ( i = 0; i < Limit; i++ )
Aig_InfoXorBit( Sml_ObjSim( p, Aig_ManPi(p->pAig, i)->Id ), i+1 );
// Aig_InfoXorBit( Sml_ObjSim( p, Aig_ManPi(p->pAig, nTruePis*(p->nFrames-2) + i)->Id ), i+1 );
}
}
}
/**Function*************************************************************
Synopsis [Simulates one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sml_NodeSimulate( Sml_Man_t * p, Aig_Obj_t * pObj, int iFrame )
{
unsigned * pSims, * pSims0, * pSims1;
int fCompl, fCompl0, fCompl1, i;
int nSimWords = p->nWordsFrame;
assert( !Aig_IsComplement(pObj) );
assert( Aig_ObjIsNode(pObj) );
assert( iFrame == 0 || nSimWords < p->nWordsTotal );
// get hold of the simulation information
pSims = Fra_ObjSim(pObj) + nSimWords * iFrame;
pSims0 = Fra_ObjSim(Aig_ObjFanin0(pObj)) + nSimWords * iFrame;
pSims1 = Fra_ObjSim(Aig_ObjFanin1(pObj)) + nSimWords * iFrame;
// get complemented attributes of the children using their random info
fCompl = pObj->fPhase;
fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj));
fCompl1 = Aig_ObjPhaseReal(Aig_ObjChild1(pObj));
// simulate
if ( fCompl0 && fCompl1 )
{
if ( fCompl )
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (pSims0[i] | pSims1[i]);
else
for ( i = 0; i < nSimWords; i++ )
pSims[i] = ~(pSims0[i] | pSims1[i]);
}
else if ( fCompl0 && !fCompl1 )
{
if ( fCompl )
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (pSims0[i] | ~pSims1[i]);
else
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (~pSims0[i] & pSims1[i]);
}
else if ( !fCompl0 && fCompl1 )
{
if ( fCompl )
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (~pSims0[i] | pSims1[i]);
else
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (pSims0[i] & ~pSims1[i]);
}
else // if ( !fCompl0 && !fCompl1 )
{
if ( fCompl )
for ( i = 0; i < nSimWords; i++ )
pSims[i] = ~(pSims0[i] & pSims1[i]);
else
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (pSims0[i] & pSims1[i]);
}
}
/**Function*************************************************************
Synopsis [Simulates one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sml_NodeCopyFanin( Sml_Man_t * p, Aig_Obj_t * pObj, int iFrame )
{
unsigned * pSims, * pSims0;
int fCompl, fCompl0, i;
int nSimWords = p->nWordsFrame;
assert( !Aig_IsComplement(pObj) );
assert( Aig_ObjIsPo(pObj) );
assert( iFrame == 0 || nSimWords < p->nWordsTotal );
// get hold of the simulation information
pSims = Sml_ObjSim(p, pObj->Id) + nSimWords * iFrame;
pSims0 = Sml_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + nSimWords * iFrame;
// get complemented attributes of the children using their random info
fCompl = pObj->fPhase;
fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj));
// copy information as it is
if ( fCompl0 )
for ( i = 0; i < nSimWords; i++ )
pSims[i] = ~pSims0[i];
else
for ( i = 0; i < nSimWords; i++ )
pSims[i] = pSims0[i];
}
/**Function*************************************************************
Synopsis [Simulates one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Sml_NodeTransferNext( Sml_Man_t * p, Aig_Obj_t * pOut, Aig_Obj_t * pIn, int iFrame )
{
unsigned * pSims0, * pSims1;
int i, nSimWords = p->nWordsFrame;
assert( !Aig_IsComplement(pOut) );
assert( !Aig_IsComplement(pIn) );
assert( Aig_ObjIsPo(pOut) );
assert( Aig_ObjIsPi(pIn) );
assert( iFrame == 0 || nSimWords < p->nWordsTotal );
// get hold of the simulation information
pSims0 = Sml_ObjSim(p, pOut->Id) + nSimWords * iFrame;
pSims1 = Sml_ObjSim(p, pIn->Id) + nSimWords * (iFrame+1);
// copy information as it is
for ( i = 0; i < nSimWords; i++ )
pSims1[i] = pSims0[i];
}
/**Function*************************************************************
Synopsis [Simulates AIG manager.]
Description [Assumes that the PI simulation info is attached.]
SideEffects []
SeeAlso []
***********************************************************************/
void Sml_SimulateOne( Sml_Man_t * p )
{
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int f, i, clk;
clk = clock();
for ( f = 0; f < p->nFrames; f++ )
{
// simulate the nodes
Aig_ManForEachNode( p->pAig, pObj, i )
Sml_NodeSimulate( p, pObj, f );
if ( f == p->nFrames - 1 )
break;
// copy simulation info into outputs
Aig_ManForEachLiSeq( p->pAig, pObj, i )
Sml_NodeCopyFanin( p, pObj, f );
// copy simulation info into the inputs
// for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ )
// Sml_NodeTransferNext( p, Aig_ManLi(p->pAig, i), Aig_ManLo(p->pAig, i), f );
Aig_ManForEachLiLoSeq( p->pAig, pObjLi, pObjLo, i )
Sml_NodeTransferNext( p, pObjLi, pObjLo, f );
}
//p->timeSim += clock() - clk;
//p->nSimRounds++;
}
/**Function*************************************************************
Synopsis [Performs simulation of the uninitialized circuit.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Sml_Man_t * Sml_ManSimulateComb( Aig_Man_t * pAig, int nWords )
{
Sml_Man_t * p;
p = Sml_ManStart( pAig, 1, nWords );
Sml_ManInitialize( p, 0 );
Sml_SimulateOne( p );
return p;
}
/**Function*************************************************************
Synopsis [Performs simulation of the initialized circuit.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Sml_Man_t * Sml_ManSimulateSeq( Aig_Man_t * pAig, int nFrames, int nWords )
{
Sml_Man_t * p;
p = Sml_ManStart( pAig, nFrames, nWords );
Sml_ManInitialize( p, 1 );
Sml_SimulateOne( p );
return p;
}
/**Function*************************************************************
Synopsis [Counts the number of 1s in each siminfo of each node.] Synopsis [Counts the number of 1s in each siminfo of each node.]
Description [] Description []
...@@ -428,16 +43,16 @@ Sml_Man_t * Sml_ManSimulateSeq( Aig_Man_t * pAig, int nFrames, int nWords ) ...@@ -428,16 +43,16 @@ Sml_Man_t * Sml_ManSimulateSeq( Aig_Man_t * pAig, int nFrames, int nWords )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int * Sml_ManCountOnes( Sml_Man_t * p ) static inline int * Fra_SmlCountOnes( Fra_Sml_t * p )
{ {
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
unsigned * pSim; unsigned * pSim;
int i, k, * 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 )
{ {
pSim = Sml_ObjSim( p, i ); pSim = Fra_ObjSim( p, i );
for ( k = 0; k < p->nWordsTotal; k++ ) for ( k = 0; k < p->nWordsTotal; k++ )
pnBits[i] += Aig_WordCountOnes( pSim[k] ); pnBits[i] += Aig_WordCountOnes( pSim[k] );
} }
...@@ -455,12 +70,12 @@ int * Sml_ManCountOnes( Sml_Man_t * p ) ...@@ -455,12 +70,12 @@ int * Sml_ManCountOnes( Sml_Man_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
static inline int Sml_NodeNotImpCost( Sml_Man_t * p, int Left, int Right ) static inline int Sml_NodeNotImpWeight( Fra_Sml_t * p, int Left, int Right )
{ {
unsigned * pSimL, * pSimR; unsigned * pSimL, * pSimR;
int k, Counter = 0; int k, Counter = 0;
pSimL = Sml_ObjSim( p, Left ); pSimL = Fra_ObjSim( p, Left );
pSimR = Sml_ObjSim( p, Right ); pSimR = Fra_ObjSim( p, Right );
for ( k = 0; k < p->nWordsTotal; k++ ) for ( k = 0; k < p->nWordsTotal; k++ )
Counter += Aig_WordCountOnes( pSimL[k] & ~pSimR[k] ); Counter += Aig_WordCountOnes( pSimL[k] & ~pSimR[k] );
return Counter; return Counter;
...@@ -477,12 +92,12 @@ static inline int Sml_NodeNotImpCost( Sml_Man_t * p, int Left, int Right ) ...@@ -477,12 +92,12 @@ static inline int Sml_NodeNotImpCost( Sml_Man_t * p, int Left, int Right )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
static inline int Sml_NodeCheckImp( Sml_Man_t * p, int Left, int Right ) static inline int Sml_NodeCheckImp( Fra_Sml_t * p, int Left, int Right )
{ {
unsigned * pSimL, * pSimR; unsigned * pSimL, * pSimR;
int k; int k;
pSimL = Sml_ObjSim( p, Left ); pSimL = Fra_ObjSim( p, Left );
pSimR = Sml_ObjSim( p, Right ); pSimR = Fra_ObjSim( p, Right );
for ( k = 0; k < p->nWordsTotal; k++ ) for ( k = 0; k < p->nWordsTotal; k++ )
if ( pSimL[k] & ~pSimR[k] ) if ( pSimL[k] & ~pSimR[k] )
return 0; return 0;
...@@ -500,42 +115,69 @@ static inline int Sml_NodeCheckImp( Sml_Man_t * p, int Left, int Right ) ...@@ -500,42 +115,69 @@ static inline int Sml_NodeCheckImp( Sml_Man_t * p, int Left, int Right )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Vec_Ptr_t * Sml_ManSortUsingOnes( Sml_Man_t * p ) Vec_Ptr_t * Fra_SmlSortUsingOnes( Fra_Sml_t * p, int fLatchCorr )
{ {
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
Vec_Ptr_t * vNodes; Vec_Ptr_t * vNodes;
int i, nNodes, nTotal, nBits, * pnNodes, * pnBits, * pMemory; int i, nNodes, nTotal, nBits, * pnNodes, * pnBits, * pMemory;
assert( p->nWordsTotal > 0 );
// count 1s in each node's siminfo // count 1s in each node's siminfo
pnBits = Sml_ManCountOnes( p ); pnBits = Fra_SmlCountOnes( p );
// count number of nodes having that many 1s // count number of nodes having that many 1s
nBits = p->nWordsTotal * 32;
assert( nBits >= 32 );
nNodes = 0; nNodes = 0;
pnNodes = ALLOC( int, nBits ); nBits = p->nWordsTotal * 32;
memset( pnNodes, 0, sizeof(int) * nBits ); pnNodes = ALLOC( int, nBits + 1 );
memset( pnNodes, 0, sizeof(int) * (nBits + 1) );
Aig_ManForEachObj( p->pAig, pObj, i ) Aig_ManForEachObj( p->pAig, pObj, i )
{ {
if ( i == 0 ) continue; if ( i == 0 ) continue;
assert( pnBits[i] < nBits ); // "<" because of normalized info // skip non-PI and non-internal nodes
if ( fLatchCorr )
{
if ( !Aig_ObjIsPi(pObj) )
continue;
}
else
{
if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
continue;
}
// skip nodes participating in the classes
// if ( Fra_ClassObjRepr(pObj) )
// continue;
assert( pnBits[i] <= nBits ); // "<" because of normalized info
pnNodes[pnBits[i]]++; pnNodes[pnBits[i]]++;
nNodes++; nNodes++;
} }
// allocate memory for all the nodes // allocate memory for all the nodes
pMemory = ALLOC( int, nNodes + nBits ); pMemory = ALLOC( int, nNodes + nBits + 1 );
// markup the memory for each node // markup the memory for each node
vNodes = Vec_PtrAlloc( nBits ); vNodes = Vec_PtrAlloc( nBits + 1 );
Vec_PtrPush( vNodes, pMemory ); Vec_PtrPush( vNodes, pMemory );
Aig_ManForEachObj( p->pAig, pObj, i ) for ( i = 1; i <= nBits; i++ )
{ {
if ( i == 0 ) continue; pMemory += pnNodes[i-1] + 1;
pMemory += pnBits[i-1] + 1;
Vec_PtrPush( vNodes, pMemory ); Vec_PtrPush( vNodes, pMemory );
} }
// add the nodes // add the nodes
memset( pnNodes, 0, sizeof(int) * nBits ); memset( pnNodes, 0, sizeof(int) * (nBits + 1) );
Aig_ManForEachObj( p->pAig, pObj, i ) Aig_ManForEachObj( p->pAig, pObj, i )
{ {
if ( i == 0 ) continue; if ( i == 0 ) continue;
// skip non-PI and non-internal nodes
if ( fLatchCorr )
{
if ( !Aig_ObjIsPi(pObj) )
continue;
}
else
{
if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
continue;
}
// skip nodes participating in the classes
// if ( Fra_ClassObjRepr(pObj) )
// continue;
pMemory = Vec_PtrEntry( vNodes, pnBits[i] ); pMemory = Vec_PtrEntry( vNodes, pnBits[i] );
pMemory[ pnNodes[pnBits[i]]++ ] = i; pMemory[ pnNodes[pnBits[i]]++ ] = i;
} }
...@@ -546,13 +188,15 @@ Vec_Ptr_t * Sml_ManSortUsingOnes( Sml_Man_t * p ) ...@@ -546,13 +188,15 @@ Vec_Ptr_t * Sml_ManSortUsingOnes( Sml_Man_t * p )
pMemory[ pnNodes[i]++ ] = 0; pMemory[ pnNodes[i]++ ] = 0;
nTotal += pnNodes[i]; nTotal += pnNodes[i];
} }
assert( nTotal == nNodes + nBits ); assert( nTotal == nNodes + nBits + 1 );
free( pnNodes );
free( pnBits );
return vNodes; return vNodes;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Compares two implications using their cost.] Synopsis [Returns the array of implications with the highest cost.]
Description [] Description []
...@@ -561,15 +205,41 @@ Vec_Ptr_t * Sml_ManSortUsingOnes( Sml_Man_t * p ) ...@@ -561,15 +205,41 @@ Vec_Ptr_t * Sml_ManSortUsingOnes( Sml_Man_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Sml_CompareCost( int * pNum1, int * pNum2 ) Vec_Int_t * Fra_SmlSelectMaxCost( Vec_Int_t * vImps, int * pCosts, int nCostMax, int nImpLimit )
{ {
int Cost1 = s_ImpCost[*pNum1]; Vec_Int_t * vImpsNew;
int Cost2 = s_ImpCost[*pNum2]; int * pCostCount, nImpCount, Imp, i, c;
if ( Cost1 > Cost2 ) assert( Vec_IntSize(vImps) >= nImpLimit );
return -1; // count how many implications have each cost
if ( Cost1 < Cost2 ) pCostCount = ALLOC( int, nCostMax + 1 );
return 1; memset( pCostCount, 0, sizeof(int) * (nCostMax + 1) );
return 0; for ( i = 0; i < Vec_IntSize(vImps); i++ )
{
assert( pCosts[i] <= nCostMax );
pCostCount[ pCosts[i] ]++;
}
assert( pCostCount[0] == 0 );
// select the bound on the cost (above this bound, implication will be included)
nImpCount = 0;
for ( c = nCostMax; c > 0; c-- )
{
nImpCount += pCostCount[c];
if ( nImpCount >= nImpLimit )
break;
}
// printf( "Cost range >= %d.\n", c );
// collect implications with the given costs
vImpsNew = Vec_IntAlloc( nImpLimit );
Vec_IntForEachEntry( vImps, Imp, i )
{
if ( pCosts[i] < c )
continue;
Vec_IntPush( vImpsNew, Imp );
if ( Vec_IntSize( vImpsNew ) == nImpLimit )
break;
}
free( pCostCount );
return vImpsNew;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -602,72 +272,103 @@ int Sml_CompareMaxId( unsigned short * pImp1, unsigned short * pImp2 ) ...@@ -602,72 +272,103 @@ int Sml_CompareMaxId( unsigned short * pImp1, unsigned short * pImp2 )
(1) they hold using sequential simulation information (1) they hold using sequential simulation information
(2) they do not hold using combinational simulation information (2) they do not hold using combinational simulation information
(3) they have as high expressive power as possible (heuristically) (3) they have as high expressive power as possible (heuristically)
- this means they are relatively far in terms of Humming distance that is, they are easy to disprove combinationally
meaning their complement covers a larger Boolean space meaning they cover relatively larger sequential subspace.]
- they are easy to disprove combinationally
meaning they cover relatively a larger sequential subspace.]
SideEffects [The managers should have the first pattern (000...)] SideEffects []
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Vec_Int_t * Sml_ManImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit ) Vec_Int_t * Fra_ImpDerive( Fra_Man_t * p, int nImpMaxLimit, int nImpUseLimit, int fLatchCorr )
{ {
Sml_Man_t * pSeq, * pComb; // Aig_Obj_t * pObj;
int nSimWords = 64;
Fra_Sml_t * pSeq, * pComb;
Vec_Int_t * vImps, * vTemp; Vec_Int_t * vImps, * vTemp;
Vec_Ptr_t * vNodes; Vec_Ptr_t * vNodes;
int * pNodesI, * pNodesK, * pNumbers; int * pImpCosts, * pNodesI, * pNodesK;
int i, k, Imp; int nImpsTotal = 0, nImpsTried = 0, nImpsNonSeq = 0, nImpsComb = 0, nImpsCollected = 0;
int CostMin = AIG_INFINITY, CostMax = 0;
int i, k, Imp, clk = clock();
assert( nImpMaxLimit > 0 && nImpUseLimit > 0 && nImpUseLimit <= nImpMaxLimit ); assert( nImpMaxLimit > 0 && nImpUseLimit > 0 && nImpUseLimit <= nImpMaxLimit );
// normalize both managers // normalize both managers
pComb = Sml_ManSimulateComb( p->pManAig, 32 ); pComb = Fra_SmlSimulateComb( p->pManAig, nSimWords );
pSeq = Sml_ManSimulateSeq( p->pManAig, 32, 1 ); pSeq = Fra_SmlSimulateSeq( p->pManAig, nSimWords, 1 );
// get the nodes sorted by the number of 1s // get the nodes sorted by the number of 1s
vNodes = Sml_ManSortUsingOnes( pSeq ); 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
for ( k = nSimWords * 32; k > 0; k-- )
for ( i = k - 1; i > 0; i-- )
for ( pNodesI = Vec_PtrEntry( vNodes, i ); *pNodesI; pNodesI++ )
for ( pNodesK = Vec_PtrEntry( vNodes, k ); *pNodesK; pNodesK++ )
nImpsTotal++;
// compute implications and their costs // compute implications and their costs
s_ImpCost = ALLOC( int, nImpMaxLimit ); pImpCosts = ALLOC( int, nImpMaxLimit );
vImps = Vec_IntAlloc( nImpMaxLimit ); vImps = Vec_IntAlloc( nImpMaxLimit );
for ( k = pSeq->nWordsTotal * 32 - 1; k >= 0; k-- ) for ( k = pSeq->nWordsTotal * 32; k > 0; k-- )
for ( i = k - 1; i >= 0; i-- ) for ( i = k - 1; i > 0; i-- )
{ {
for ( pNodesI = Vec_PtrEntry( vNodes, i ); *pNodesI; pNodesI++ ) for ( pNodesI = Vec_PtrEntry( vNodes, i ); *pNodesI; pNodesI++ )
for ( pNodesK = Vec_PtrEntry( vNodes, k ); *pNodesK; pNodesK++ ) for ( pNodesK = Vec_PtrEntry( vNodes, k ); *pNodesK; pNodesK++ )
{ {
if ( Sml_NodeCheckImp(pSeq, *pNodesI, *pNodesK) && nImpsTried++;
!Sml_NodeCheckImp(pComb, *pNodesI, *pNodesK) ) if ( !Sml_NodeCheckImp(pSeq, *pNodesI, *pNodesK) )
{ {
nImpsNonSeq++;
continue;
}
if ( Sml_NodeCheckImp(pComb, *pNodesI, *pNodesK) )
{
nImpsComb++;
continue;
}
// printf( "d=%d c=%d ", k-i, Sml_NodeNotImpWeight(pComb, *pNodesI, *pNodesK) );
nImpsCollected++;
Imp = Sml_ImpCreate( *pNodesI, *pNodesK ); Imp = Sml_ImpCreate( *pNodesI, *pNodesK );
s_ImpCost[ Vec_IntSize(vImps) ] = Sml_NodeNotImpCost(pComb, *pNodesI, *pNodesK); pImpCosts[ Vec_IntSize(vImps) ] = Sml_NodeNotImpWeight(pComb, *pNodesI, *pNodesK);
CostMin = AIG_MIN( CostMin, pImpCosts[ Vec_IntSize(vImps) ] );
CostMax = AIG_MAX( CostMax, pImpCosts[ Vec_IntSize(vImps) ] );
Vec_IntPush( vImps, Imp ); Vec_IntPush( vImps, Imp );
}
if ( Vec_IntSize(vImps) == nImpMaxLimit ) if ( Vec_IntSize(vImps) == nImpMaxLimit )
goto finish; goto finish;
} }
} }
finish: finish:
Sml_ManStop( pComb ); Fra_SmlStop( pComb );
Sml_ManStop( pSeq ); Fra_SmlStop( pSeq );
// select implications with the highest cost
if ( Vec_IntSize(vImps) > nImpUseLimit )
{
vImps = Fra_SmlSelectMaxCost( vTemp = vImps, pImpCosts, nSimWords * 32, nImpUseLimit );
Vec_IntFree( vTemp );
}
// sort implications by their cost
pNumbers = ALLOC( int, Vec_IntSize(vImps) );
for ( i = 0; i < Vec_IntSize(vImps); i++ )
pNumbers[i] = i;
qsort( (void *)pNumbers, Vec_IntSize(vImps), sizeof(int),
(int (*)(const void *, const void *)) Sml_CompareCost );
// reorder implications
vTemp = Vec_IntAlloc( nImpUseLimit );
for ( i = 0; i < nImpUseLimit; i++ )
Vec_IntPush( vTemp, Vec_IntEntry( vImps, pNumbers[i] ) );
Vec_IntFree( vImps ); vImps = vTemp;
// dealloc // dealloc
free( pNumbers ); free( pImpCosts );
free( s_ImpCost ); s_ImpCost = NULL;
free( Vec_PtrEntry(vNodes, 0) ); free( Vec_PtrEntry(vNodes, 0) );
Vec_PtrFree( vNodes ); Vec_PtrFree( vNodes );
// order implications by the max ID involved // reorder implications topologically
qsort( (void *)Vec_IntArray(vImps), Vec_IntSize(vImps), sizeof(int), qsort( (void *)Vec_IntArray(vImps), Vec_IntSize(vImps), sizeof(int),
(int (*)(const void *, const void *)) Sml_CompareMaxId ); (int (*)(const void *, const void *)) Sml_CompareMaxId );
if ( p->pPars->fVerbose )
{
printf( "Tot = %d. Try = %d. NonS = %d. C = %d. Found = %d. Cost = [%d - %d] ",
nImpsTotal, nImpsTried, nImpsNonSeq, nImpsComb, nImpsCollected, CostMin, CostMax );
PRT( "Time", clock() - clk );
}
return vImps; return vImps;
} }
...@@ -678,7 +379,7 @@ finish: ...@@ -678,7 +379,7 @@ finish:
/**Function************************************************************* /**Function*************************************************************
Synopsis [] Synopsis [Add implication clauses to the SAT solver.]
Description [] Description []
...@@ -687,17 +388,32 @@ finish: ...@@ -687,17 +388,32 @@ finish:
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps ) void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps, int * pSatVarNums )
{ {
sat_solver * pSat = p->pSat; sat_solver * pSat = p->pSat;
Aig_Obj_t * pLeft, * pRight; Aig_Obj_t * pLeft, * pRight;
Aig_Obj_t * pLeftF, * pRightF; Aig_Obj_t * pLeftF, * pRightF;
int pLits[2], Imp, Left, Right, i, f, status; int pLits[2], Imp, Left, Right, i, f, status;
int fComplL, fComplR;
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, Sml_ImpLeft(Imp) );
pRight = Aig_ManObj( p->pManAig, Sml_ImpRight(Imp) ); pRight = Aig_ManObj( p->pManAig, Sml_ImpRight(Imp) );
// check if all the nodes are present
for ( f = 0; f < p->pPars->nFramesK; f++ )
{
// map these info fraig
pLeftF = Fra_ObjFraig( pLeft, f );
pRightF = Fra_ObjFraig( pRight, f );
if ( Aig_ObjIsNone(Aig_Regular(pLeftF)) || Aig_ObjIsNone(Aig_Regular(pRightF)) )
{
Vec_IntWriteEntry( vImps, i, 0 );
break;
}
}
if ( f < p->pPars->nFramesK )
continue;
// add constraints in each timeframe // add constraints in each timeframe
for ( f = 0; f < p->pPars->nFramesK; f++ ) for ( f = 0; f < p->pPars->nFramesK; f++ )
{ {
...@@ -705,14 +421,17 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps ) ...@@ -705,14 +421,17 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps )
pLeftF = Fra_ObjFraig( pLeft, f ); pLeftF = Fra_ObjFraig( pLeft, f );
pRightF = Fra_ObjFraig( pRight, f ); pRightF = Fra_ObjFraig( pRight, f );
// get the corresponding SAT numbers // get the corresponding SAT numbers
Left = Fra_ObjSatNum( Aig_Regular(pLeftF) ); Left = pSatVarNums[ Aig_Regular(pLeftF)->Id ];
Right = Fra_ObjSatNum( Aig_Regular(pRightF) ); Right = pSatVarNums[ Aig_Regular(pRightF)->Id ];
assert( Left > 0 && Left < p->nSatVars ); assert( Left > 0 && Left < p->nSatVars );
assert( Right > 0 && Right < p->nSatVars ); assert( Right > 0 && Right < p->nSatVars );
// get the complemented attributes
fComplL = pLeft->fPhase ^ Aig_IsComplement(pLeftF);
fComplR = pRight->fPhase ^ Aig_IsComplement(pRightF);
// get the constaint // get the constaint
// L => R L' v R L & R' // L => R L' v R (complement = L & R')
pLits[0] = 2 * Left + !Aig_ObjPhaseReal(pLeftF); pLits[0] = 2 * Left + !fComplL;
pLits[1] = 2 * Right + Aig_ObjPhaseReal(pRightF); pLits[1] = 2 * Right + fComplR;
// add contraint to solver // add contraint to solver
if ( !sat_solver_addclause( pSat, pLits, pLits + 2 ) ) if ( !sat_solver_addclause( pSat, pLits, pLits + 2 ) )
{ {
...@@ -728,6 +447,9 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps ) ...@@ -728,6 +447,9 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps )
sat_solver_delete( pSat ); sat_solver_delete( pSat );
p->pSat = NULL; p->pSat = NULL;
} }
// printf( "Total imps = %d. ", Vec_IntSize(vImps) );
Fra_ImpCompactArray( vImps );
// printf( "Valid imps = %d. \n", Vec_IntSize(vImps) );
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -744,9 +466,13 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps ) ...@@ -744,9 +466,13 @@ void Fra_ImpAddToSolver( Fra_Man_t * p, Vec_Int_t * vImps )
int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, int Pos ) int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, int Pos )
{ {
Aig_Obj_t * pLeft, * pRight; Aig_Obj_t * pLeft, * pRight;
Aig_Obj_t * pLeftF, * pRightF;
int i, Imp, Left, Right, Max; int i, Imp, Left, Right, Max;
int fComplL, fComplR;
Vec_IntForEachEntryStart( vImps, Imp, i, Pos ) Vec_IntForEachEntryStart( vImps, Imp, i, Pos )
{ {
if ( Imp == 0 )
continue;
Left = Sml_ImpLeft(Imp); Left = Sml_ImpLeft(Imp);
Right = Sml_ImpRight(Imp); Right = Sml_ImpRight(Imp);
Max = AIG_MAX( Left, Right ); Max = AIG_MAX( Left, Right );
...@@ -756,12 +482,33 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in ...@@ -756,12 +482,33 @@ int Fra_ImpCheckForNode( Fra_Man_t * p, Vec_Int_t * vImps, Aig_Obj_t * pNode, in
// get the corresponding nodes // get the corresponding nodes
pLeft = Aig_ManObj( p->pManAig, Left ); pLeft = Aig_ManObj( p->pManAig, Left );
pRight = Aig_ManObj( p->pManAig, Right ); pRight = Aig_ManObj( p->pManAig, Right );
// get the corresponding FRAIG nodes
pLeftF = Fra_ObjFraig( pLeft, p->pPars->nFramesK );
pRightF = Fra_ObjFraig( pRight, p->pPars->nFramesK );
// get the complemented attributes
fComplL = pLeft->fPhase ^ Aig_IsComplement(pLeftF);
fComplR = pRight->fPhase ^ Aig_IsComplement(pRightF);
// check equality
if ( Aig_Regular(pLeftF) == Aig_Regular(pRightF) )
{
// assert( fComplL == fComplR );
// if ( fComplL != fComplR )
// printf( "Fra_ImpCheckForNode(): Unexpected situation!\n" );
if ( fComplL != fComplR )
Vec_IntWriteEntry( vImps, i, 0 );
continue;
}
// check the implication // check the implication
// - if true, a clause is added // - if true, a clause is added
// - if false, a cex is simulated // - if false, a cex is simulated
// Fra_NodesAreImp( p, pLeft, pRight );
// make sure the implication is refined // make sure the implication is refined
assert( Vec_IntEntry(vImps, Pos) == 0 ); if ( Fra_NodesAreImp( p, Aig_Regular(pLeftF), Aig_Regular(pRightF), fComplL, fComplR ) == 0 )
{
Fra_SmlResimulate( p );
if ( Vec_IntEntry(vImps, i) != 0 )
printf( "Fra_ImpCheckForNode(): Implication is not refined!\n" );
assert( Vec_IntEntry(vImps, i) == 0 );
}
} }
return i; return i;
} }
...@@ -789,10 +536,11 @@ int Fra_ImpRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vImps ) ...@@ -789,10 +536,11 @@ int Fra_ImpRefineUsingCex( Fra_Man_t * p, Vec_Int_t * vImps )
pLeft = Aig_ManObj( p->pManAig, Sml_ImpLeft(Imp) ); pLeft = Aig_ManObj( p->pManAig, Sml_ImpLeft(Imp) );
pRight = Aig_ManObj( p->pManAig, Sml_ImpRight(Imp) ); pRight = Aig_ManObj( p->pManAig, Sml_ImpRight(Imp) );
// check if implication holds using this simulation info // check if implication holds using this simulation info
if ( !Sml_NodeCheckImp(p->pSim, pLeft->Id, pRight->Id) ) if ( !Sml_NodeCheckImp(p->pSml, pLeft->Id, pRight->Id) )
{ {
Vec_IntWriteEntry( vImps, i, 0 ); Vec_IntWriteEntry( vImps, i, 0 );
RetValue = 1; RetValue = 1;
p->pCla->fRefinement = 1;
} }
} }
return RetValue; return RetValue;
......
...@@ -198,13 +198,14 @@ Aig_Man_t * Fra_FramesWithClasses( Fra_Man_t * p ) ...@@ -198,13 +198,14 @@ Aig_Man_t * Fra_FramesWithClasses( Fra_Man_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite, int fLatchCorr, int fVerbose, int * pnIter ) Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose, int * pnIter )
{ {
Fra_Man_t * p; Fra_Man_t * p;
Fra_Par_t Pars, * pPars = &Pars; Fra_Par_t Pars, * pPars = &Pars;
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 nIter, i, clk = clock(), clk2; int nIter, i, clk = clock(), clk2;
if ( Aig_ManNodeNum(pManAig) == 0 ) if ( Aig_ManNodeNum(pManAig) == 0 )
...@@ -223,15 +224,26 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite, ...@@ -223,15 +224,26 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite,
pPars->fVerbose = fVerbose; pPars->fVerbose = fVerbose;
pPars->fRewrite = fRewrite; pPars->fRewrite = fRewrite;
pPars->fLatchCorr = fLatchCorr; pPars->fLatchCorr = fLatchCorr;
pPars->fUseImps = fUseImps;
// start the fraig manager for this run // start the fraig manager for this run
p = Fra_ManStart( pManAig, pPars ); p = Fra_ManStart( pManAig, pPars );
// derive and refine e-classes using K initialized frames // derive and refine e-classes using K initialized frames
// if ( fLatchCorr ) // p->pSml = Fra_SmlStart( pManAig, pPars->nFramesK + 1, pPars->nSimWords );
// Fra_ClassesLatchCorr( p ); // Fra_SmlSimulate( p, 1 );
// else
Fra_Simulate( p, 1 ); // remember that strange bug: r iscas/blif/s5378.blif ; st; ssw -F 4; sec -F 10
// refine e-classes using sequential simulation? // refine the classes with more simulation rounds
p->pSml = Fra_SmlSimulateSeq( pManAig, 32, 2 );
Fra_ClassesPrepare( p->pCla, p->pPars->fLatchCorr );
// Fra_ClassesPostprocess( p->pCla );
// allocate new simulation manager for simulating counter-examples
Fra_SmlStop( p->pSml );
p->pSml = Fra_SmlStart( pManAig, pPars->nFramesK + 1, pPars->nSimWords );
// select the most expressive implications
if ( pPars->fUseImps )
p->pCla->vImps = Fra_ImpDerive( p, 5000000, 5000, pPars->fLatchCorr );
p->nLitsZero = Vec_PtrSize( p->pCla->vClasses1 ); p->nLitsZero = Vec_PtrSize( p->pCla->vClasses1 );
p->nLitsBeg = Fra_ClassesCountLits( p->pCla ); p->nLitsBeg = Fra_ClassesCountLits( p->pCla );
...@@ -251,18 +263,13 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite, ...@@ -251,18 +263,13 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite,
// perform AIG rewriting // perform AIG rewriting
if ( p->pPars->fRewrite ) if ( p->pPars->fRewrite )
Fra_FraigInductionRewrite( p ); Fra_FraigInductionRewrite( p );
// report the intermediate results
if ( fVerbose )
{
printf( "%3d : Const = %6d. Class = %6d. L = %6d. LR = %6d. N = %6d. NR = %6d.\n",
nIter, Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses),
Fra_ClassesCountLits(p->pCla), p->pManFraig->nAsserts,
Aig_ManNodeNum(p->pManAig), Aig_ManNodeNum(p->pManFraig) );
}
// bug: r iscas/blif/s1238.blif ; st; ssw -v
// convert the manager to SAT solver (the last nLatches outputs are inputs) // convert the manager to SAT solver (the last nLatches outputs are inputs)
// pCnf = Cnf_Derive( p->pManFraig, Aig_ManRegNum(p->pManFraig) ); if ( pPars->fUseImps )
pCnf = Cnf_DeriveSimple( p->pManFraig, Aig_ManRegNum(p->pManFraig) ); pCnf = Cnf_DeriveSimple( p->pManFraig, Aig_ManRegNum(p->pManFraig) );
else
pCnf = Cnf_Derive( p->pManFraig, Aig_ManRegNum(p->pManFraig) );
//Cnf_DataWriteIntoFile( pCnf, "temp.cnf", 1 ); //Cnf_DataWriteIntoFile( pCnf, "temp.cnf", 1 );
p->pSat = Cnf_DataWriteIntoSolver( pCnf ); p->pSat = Cnf_DataWriteIntoSolver( pCnf );
...@@ -270,6 +277,12 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite, ...@@ -270,6 +277,12 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite,
assert( p->pSat != NULL ); assert( p->pSat != NULL );
if ( p->pSat == NULL ) if ( p->pSat == NULL )
printf( "Fra_FraigInduction(): Computed CNF is not valid.\n" ); printf( "Fra_FraigInduction(): Computed CNF is not valid.\n" );
if ( pPars->fUseImps )
{
Fra_ImpAddToSolver( p, p->pCla->vImps, pCnf->pVarNums );
if ( p->pSat == NULL )
printf( "Fra_FraigInduction(): Adding implicationsn to CNF led to a conflict.\n" );
}
// set the pointers to the manager // set the pointers to the manager
Aig_ManForEachObj( p->pManFraig, pObj, i ) Aig_ManForEachObj( p->pManFraig, pObj, i )
...@@ -295,9 +308,20 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite, ...@@ -295,9 +308,20 @@ Aig_Man_t * Fra_FraigInduction( Aig_Man_t * pManAig, int nFramesK, int fRewrite,
} }
Cnf_DataFree( pCnf ); Cnf_DataFree( pCnf );
*/ */
// report the intermediate results
if ( fVerbose )
{
printf( "%3d : Const = %6d. Class = %6d. L = %6d. LR = %6d. I = %6d. NR = %6d.\n",
nIter, Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses),
Fra_ClassesCountLits(p->pCla), p->pManFraig->nAsserts,
p->pCla->vImps? Vec_IntSize(p->pCla->vImps) : 0, Aig_ManNodeNum(p->pManFraig) );
}
// perform sweeping // perform sweeping
p->nSatCallsRecent = 0;
p->nSatCallsSkipped = 0;
Fra_FraigSweep( p ); Fra_FraigSweep( p );
// printf( "Recent SAT called = %d. Skipped = %d.\n", p->nSatCallsRecent, p->nSatCallsSkipped );
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" );
......
...@@ -77,8 +77,6 @@ void Fra_ParamsDefaultSeq( Fra_Par_t * pPars ) ...@@ -77,8 +77,6 @@ void Fra_ParamsDefaultSeq( Fra_Par_t * pPars )
pPars->fPatScores = 0; // enables simulation pattern scoring pPars->fPatScores = 0; // enables simulation pattern scoring
pPars->MaxScore = 25; // max score after which resimulation is used pPars->MaxScore = 25; // max score after which resimulation is used
pPars->fDoSparse = 1; // skips sparse functions pPars->fDoSparse = 1; // skips sparse functions
// pPars->dActConeRatio = 0.05; // the ratio of cone to be bumped
// pPars->dActConeBumpMax = 5.0; // the largest bump of activity
pPars->dActConeRatio = 0.3; // the ratio of cone to be bumped pPars->dActConeRatio = 0.3; // the ratio of cone to be bumped
pPars->dActConeBumpMax = 10.0; // the largest bump of activity pPars->dActConeBumpMax = 10.0; // the largest bump of activity
pPars->nBTLimitNode =10000000; // conflict limit at a node pPars->nBTLimitNode =10000000; // conflict limit at a node
...@@ -112,15 +110,9 @@ Fra_Man_t * Fra_ManStart( Aig_Man_t * pManAig, Fra_Par_t * pPars ) ...@@ -112,15 +110,9 @@ Fra_Man_t * Fra_ManStart( Aig_Man_t * pManAig, Fra_Par_t * pPars )
p->pManAig = pManAig; p->pManAig = pManAig;
p->nSizeAlloc = Aig_ManObjIdMax( pManAig ) + 1; p->nSizeAlloc = Aig_ManObjIdMax( pManAig ) + 1;
p->nFramesAll = pPars->nFramesK + 1; p->nFramesAll = pPars->nFramesK + 1;
// allocate simulation info
p->nSimWords = pPars->nSimWords * p->nFramesAll;
p->pSimWords = ALLOC( unsigned, p->nSizeAlloc * p->nSimWords );
// clean simulation info of the constant node
memset( p->pSimWords, 0, sizeof(unsigned) * p->nSizeAlloc * p->nSimWords );
// allocate storage for sim pattern // allocate storage for sim pattern
p->nPatWords = Aig_BitWordNum( Aig_ManPiNum(pManAig) * p->nFramesAll ); p->nPatWords = Aig_BitWordNum( Aig_ManPiNum(pManAig) * p->nFramesAll );
p->pPatWords = ALLOC( unsigned, p->nPatWords ); p->pPatWords = ALLOC( unsigned, p->nPatWords );
p->pPatScores = ALLOC( int, 32 * p->nSimWords );
p->vPiVars = Vec_PtrAlloc( 100 ); p->vPiVars = Vec_PtrAlloc( 100 );
// equivalence classes // equivalence classes
p->pCla = Fra_ClassesStart( pManAig ); p->pCla = Fra_ClassesStart( pManAig );
...@@ -238,21 +230,20 @@ void Fra_ManFinalizeComb( Fra_Man_t * p ) ...@@ -238,21 +230,20 @@ void Fra_ManFinalizeComb( Fra_Man_t * p )
void Fra_ManStop( Fra_Man_t * p ) void Fra_ManStop( Fra_Man_t * p )
{ {
int i; int i;
if ( p->pPars->fVerbose )
Fra_ManPrint( p );
for ( i = 0; i < p->nSizeAlloc; i++ ) for ( i = 0; i < p->nSizeAlloc; i++ )
if ( p->pMemFanins[i] && p->pMemFanins[i] != (void *)1 ) if ( p->pMemFanins[i] && p->pMemFanins[i] != (void *)1 )
Vec_PtrFree( p->pMemFanins[i] ); Vec_PtrFree( p->pMemFanins[i] );
if ( p->pPars->fVerbose )
Fra_ManPrint( p );
if ( p->vTimeouts ) Vec_PtrFree( p->vTimeouts ); if ( p->vTimeouts ) Vec_PtrFree( p->vTimeouts );
if ( p->vPiVars ) Vec_PtrFree( p->vPiVars ); if ( p->vPiVars ) Vec_PtrFree( p->vPiVars );
if ( p->pSat ) sat_solver_delete( p->pSat ); if ( p->pSat ) sat_solver_delete( p->pSat );
if ( p->pCla ) Fra_ClassesStop( p->pCla ); if ( p->pCla ) Fra_ClassesStop( p->pCla );
if ( p->pSml ) Fra_SmlStop( p->pSml );
FREE( p->pMemFraig ); FREE( p->pMemFraig );
FREE( p->pMemFanins ); FREE( p->pMemFanins );
FREE( p->pMemSatNums ); FREE( p->pMemSatNums );
FREE( p->pPatScores );
FREE( p->pPatWords ); FREE( p->pPatWords );
FREE( p->pSimWords );
free( p ); free( p );
} }
...@@ -269,16 +260,16 @@ void Fra_ManStop( Fra_Man_t * p ) ...@@ -269,16 +260,16 @@ void Fra_ManStop( Fra_Man_t * p )
***********************************************************************/ ***********************************************************************/
void Fra_ManPrint( Fra_Man_t * p ) void Fra_ManPrint( Fra_Man_t * p )
{ {
double nMemory = 1.0*Aig_ManObjIdMax(p->pManAig)*((p->nSimWords+2)*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->nSimWords, p->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 );
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. Zero = %d. C-lim = %d. Vars = %d.\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->nLitsZero, p->pPars->nBTLimitNode, p->nSatVars );
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 );
if ( p->pSat ) Sat_SolverPrintStats( stdout, p->pSat ); if ( p->pSat ) Sat_SolverPrintStats( stdout, p->pSat );
PRT( "AIG simulation ", p->timeSim ); PRT( "AIG simulation ", p->pSml->timeSim );
PRT( "AIG traversal ", p->timeTrav ); PRT( "AIG traversal ", p->timeTrav );
if ( p->timeRwr ) if ( p->timeRwr )
{ {
......
...@@ -66,6 +66,7 @@ int Fra_NodesAreEquiv( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) ...@@ -66,6 +66,7 @@ int Fra_NodesAreEquiv( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
} }
p->nSatCalls++; p->nSatCalls++;
p->nSatCallsRecent++;
// make sure the solver is allocated and has enough variables // make sure the solver is allocated and has enough variables
if ( p->pSat == NULL ) if ( p->pSat == NULL )
...@@ -188,6 +189,110 @@ p->timeSatFail += clock() - clk; ...@@ -188,6 +189,110 @@ p->timeSatFail += clock() - clk;
/**Function************************************************************* /**Function*************************************************************
Synopsis [Runs the result of test for pObj => pNew.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Fra_NodesAreImp( Fra_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew, int fComplL, int fComplR )
{
int pLits[4], RetValue, RetValue1, nBTLimit, clk, clk2 = clock();
int status;
// make sure the nodes are not complemented
assert( !Aig_IsComplement(pNew) );
assert( !Aig_IsComplement(pOld) );
assert( pNew != pOld );
// if at least one of the nodes is a failed node, perform adjustments:
// if the backtrack limit is small, simply skip this node
// if the backtrack limit is > 10, take the quare root of the limit
nBTLimit = p->pPars->nBTLimitNode;
/*
if ( !p->pPars->fSpeculate && p->pPars->nFramesK == 0 && (nBTLimit > 0 && (pOld->fMarkB || pNew->fMarkB)) )
{
p->nSatFails++;
// fail immediately
// return -1;
if ( nBTLimit <= 10 )
return -1;
nBTLimit = (int)pow(nBTLimit, 0.7);
}
*/
p->nSatCalls++;
// make sure the solver is allocated and has enough variables
if ( p->pSat == NULL )
{
p->pSat = sat_solver_new();
p->nSatVars = 1;
sat_solver_setnvars( p->pSat, 1000 );
}
// if the nodes do not have SAT variables, allocate them
Fra_NodeAddToSolver( p, pOld, pNew );
if ( p->pSat->qtail != p->pSat->qhead )
{
status = sat_solver_simplify(p->pSat);
assert( status != 0 );
assert( p->pSat->qtail == p->pSat->qhead );
}
// prepare variable activity
if ( p->pPars->fConeBias )
Fra_SetActivityFactors( p, pOld, pNew );
// solve under assumptions
// A = 1; B = 0 OR A = 1; B = 1
clk = clock();
// pLits[0] = toLitCond( Fra_ObjSatNum(pOld), 0 );
// pLits[1] = toLitCond( Fra_ObjSatNum(pNew), pOld->fPhase == pNew->fPhase );
pLits[0] = toLitCond( Fra_ObjSatNum(pOld), fComplL );
pLits[1] = toLitCond( Fra_ObjSatNum(pNew), !fComplR );
//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + 2,
(sint64)nBTLimit, (sint64)0,
p->nBTLimitGlobal, p->nInsLimitGlobal );
p->timeSat += clock() - clk;
if ( RetValue1 == l_False )
{
p->timeSatUnsat += clock() - clk;
pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
assert( RetValue );
// continue solving the other implication
p->nSatCallsUnsat++;
}
else if ( RetValue1 == l_True )
{
p->timeSatSat += clock() - clk;
Fra_SavePattern( p );
p->nSatCallsSat++;
return 0;
}
else // if ( RetValue1 == l_Undef )
{
p->timeSatFail += clock() - clk;
// mark the node as the failed node
if ( pOld != p->pManFraig->pConst1 )
pOld->fMarkB = 1;
pNew->fMarkB = 1;
p->nSatFailsReal++;
return -1;
}
// return SAT proof
p->nSatProof++;
return 1;
}
/**Function*************************************************************
Synopsis [Runs equivalence test for one node.] Synopsis [Runs equivalence test for one node.]
Description [Returns the fraiged node.] Description [Returns the fraiged node.]
......
...@@ -47,7 +47,7 @@ int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose ...@@ -47,7 +47,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, nFrames, 0, 0, fVeryVerbose, &nIter ); pNew = Fra_FraigInduction( p, nFrames, 0, 0, 0, fVeryVerbose, &nIter );
} }
else else
{ {
...@@ -55,7 +55,7 @@ int Fra_FraigSec( Aig_Man_t * p, int nFramesFix, int fVerbose, int fVeryVerbose ...@@ -55,7 +55,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, nFrames, 0, 0, fVeryVerbose, &nIter ); pNew = Fra_FraigInduction( p, nFrames, 0, 0, 0, fVeryVerbose, &nIter );
RetValue = Fra_FraigMiterStatus( pNew ); RetValue = Fra_FraigMiterStatus( pNew );
if ( fVerbose ) if ( fVerbose )
{ {
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [Assigns random patterns to the PI node.] Synopsis [Returns 1 if simulation info is composed of all zeros.]
Description [] Description []
...@@ -39,19 +39,21 @@ ...@@ -39,19 +39,21 @@
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_NodeAssignRandom( Fra_Man_t * p, Aig_Obj_t * pObj ) int Fra_NodeHasZeroSim( Aig_Obj_t * pObj )
{ {
Fra_Man_t * p = pObj->pData;
unsigned * pSims; unsigned * pSims;
int i; int i;
assert( Aig_ObjIsPi(pObj) ); pSims = Fra_ObjSim(p->pSml, pObj->Id);
pSims = Fra_ObjSim(pObj); for ( i = 0; i < p->pSml->nWordsTotal; i++ )
for ( i = 0; i < p->nSimWords; i++ ) if ( pSims[i] )
pSims[i] = Fra_ObjRandomSim(); return 0;
return 1;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Assigns constant patterns to the PI node.] Synopsis [Returns 1 if simulation infos are equal.]
Description [] Description []
...@@ -60,19 +62,22 @@ void Fra_NodeAssignRandom( Fra_Man_t * p, Aig_Obj_t * pObj ) ...@@ -60,19 +62,22 @@ void Fra_NodeAssignRandom( Fra_Man_t * p, Aig_Obj_t * pObj )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_NodeAssignConst( Fra_Man_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame ) int Fra_NodeCompareSims( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
{ {
unsigned * pSims; Fra_Man_t * p = pObj0->pData;
unsigned * pSims0, * pSims1;
int i; int i;
assert( Aig_ObjIsPi(pObj) ); pSims0 = Fra_ObjSim(p->pSml, pObj0->Id);
pSims = Fra_ObjSim(pObj) + p->pPars->nSimWords * iFrame; pSims1 = Fra_ObjSim(p->pSml, pObj1->Id);
for ( i = 0; i < p->pPars->nSimWords; i++ ) for ( i = 0; i < p->pSml->nWordsTotal; i++ )
pSims[i] = fConst1? ~(unsigned)0 : 0; if ( pSims0[i] != pSims1[i] )
return 0;
return 1;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Assings random simulation info for the PIs.] Synopsis [Computes hash value of the node using its simulation info.]
Description [] Description []
...@@ -81,31 +86,42 @@ void Fra_NodeAssignConst( Fra_Man_t * p, Aig_Obj_t * pObj, int fConst1, int iFra ...@@ -81,31 +86,42 @@ void Fra_NodeAssignConst( Fra_Man_t * p, Aig_Obj_t * pObj, int fConst1, int iFra
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_AssignRandom( Fra_Man_t * p, int fInit ) unsigned Fra_NodeHashSims( Aig_Obj_t * pObj )
{ {
Aig_Obj_t * pObj; Fra_Man_t * p = pObj->pData;
static int s_FPrimes[128] = {
1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
};
unsigned * pSims;
unsigned uHash;
int i; int i;
if ( fInit ) assert( p->pSml->nWordsTotal <= 128 );
{ uHash = 0;
assert( Aig_ManRegNum(p->pManAig) > 0 ); pSims = Fra_ObjSim(p->pSml, pObj->Id);
assert( Aig_ManRegNum(p->pManAig) < Aig_ManPiNum(p->pManAig) ); for ( i = 0; i < p->pSml->nWordsTotal; i++ )
// assign random info for primary inputs uHash ^= pSims[i] * s_FPrimes[i];
Aig_ManForEachPiSeq( p->pManAig, pObj, i ) return uHash;
Fra_NodeAssignRandom( p, pObj );
// assign the initial state for the latches
Aig_ManForEachLoSeq( p->pManAig, pObj, i )
Fra_NodeAssignConst( p, pObj, 0, 0 );
}
else
{
Aig_ManForEachPi( p->pManAig, pObj, i )
Fra_NodeAssignRandom( p, pObj );
}
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Assings distance-1 simulation info for the PIs.] Synopsis [Generated const 0 pattern.]
Description [] Description []
...@@ -114,48 +130,14 @@ void Fra_AssignRandom( Fra_Man_t * p, int fInit ) ...@@ -114,48 +130,14 @@ void Fra_AssignRandom( Fra_Man_t * p, int fInit )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_AssignDist1( Fra_Man_t * p, unsigned * pPat ) void Fra_SavePattern0( Fra_Man_t * p, int fInit )
{ {
Aig_Obj_t * pObj; memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
int f, i, k, Limit, nTruePis;
if ( p->pPars->nFramesK == 0 )
{
assert( p->nFramesAll == 1 );
// copy the PI info
Aig_ManForEachPi( p->pManAig, pObj, i )
Fra_NodeAssignConst( p, pObj, Aig_InfoHasBit(pPat, i), 0 );
// flip one bit
Limit = AIG_MIN( Aig_ManPiNum(p->pManAig), p->nSimWords * 32 - 1 );
for ( i = 0; i < Limit; i++ )
Aig_InfoXorBit( Fra_ObjSim( Aig_ManPi(p->pManAig,i) ), i+1 );
}
else
{
// copy the PI info for each frame
nTruePis = Aig_ManPiNum(p->pManAig) - Aig_ManRegNum(p->pManAig);
for ( f = 0; f < p->nFramesAll; f++ )
Aig_ManForEachPiSeq( p->pManAig, pObj, i )
Fra_NodeAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * f + i), f );
// copy the latch info
k = 0;
Aig_ManForEachLoSeq( p->pManAig, pObj, i )
Fra_NodeAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * p->nFramesAll + k++), 0 );
assert( p->pManFraig == NULL || nTruePis * p->nFramesAll + k == Aig_ManPiNum(p->pManFraig) );
// flip one bit of the last frame
if ( p->nFramesAll == 2 )
{
Limit = AIG_MIN( nTruePis, p->pPars->nSimWords * 32 - 1 );
for ( i = 0; i < Limit; i++ )
Aig_InfoXorBit( Fra_ObjSim( Aig_ManPi(p->pManAig, i) ), i+1 );
// Aig_InfoXorBit( Fra_ObjSim( Aig_ManPi(p->pManAig, nTruePis*(p->nFramesAll-2) + i) ), i+1 );
}
}
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Returns 1 if simulation info is composed of all zeros.] Synopsis [[Generated const 1 pattern.]
Description [] Description []
...@@ -164,21 +146,22 @@ void Fra_AssignDist1( Fra_Man_t * p, unsigned * pPat ) ...@@ -164,21 +146,22 @@ void Fra_AssignDist1( Fra_Man_t * p, unsigned * pPat )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Fra_NodeHasZeroSim( Aig_Obj_t * pObj ) void Fra_SavePattern1( Fra_Man_t * p, int fInit )
{ {
Fra_Man_t * p = pObj->pData; Aig_Obj_t * pObj;
unsigned * pSims; int i, k, nTruePis;
int i; memset( p->pPatWords, 0xff, sizeof(unsigned) * p->nPatWords );
pSims = Fra_ObjSim(pObj); if ( !fInit )
for ( i = 0; i < p->nSimWords; i++ ) return;
if ( pSims[i] ) nTruePis = Aig_ManPiNum(p->pManAig) - Aig_ManRegNum(p->pManAig);
return 0; k = 0;
return 1; Aig_ManForEachLoSeq( p->pManAig, pObj, i )
Aig_InfoXorBit( p->pPatWords, nTruePis * p->nFramesAll + k++ );
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Returns 1 if simulation infos are equal.] Synopsis [Copy pattern from the solver into the internal storage.]
Description [] Description []
...@@ -187,22 +170,27 @@ int Fra_NodeHasZeroSim( Aig_Obj_t * pObj ) ...@@ -187,22 +170,27 @@ int Fra_NodeHasZeroSim( Aig_Obj_t * pObj )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Fra_NodeCompareSims( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) void Fra_SavePattern( Fra_Man_t * p )
{ {
Fra_Man_t * p = pObj0->pData; Aig_Obj_t * pObj;
unsigned * pSims0, * pSims1;
int i; int i;
pSims0 = Fra_ObjSim(pObj0); memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
pSims1 = Fra_ObjSim(pObj1); Aig_ManForEachPi( p->pManFraig, pObj, i )
for ( i = 0; i < p->nSimWords; i++ ) if ( p->pSat->model.ptr[Fra_ObjSatNum(pObj)] == l_True )
if ( pSims0[i] != pSims1[i] ) Aig_InfoSetBit( p->pPatWords, i );
return 0; /*
return 1; printf( "Pattern: " );
Aig_ManForEachPi( p->pManFraig, pObj, i )
printf( "%d", Aig_InfoHasBit( p->pPatWords, i ) );
printf( "\n" );
*/
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Computes hash value of the node using its simulation info.] Synopsis [Creates the counter-example from the successful pattern.]
Description [] Description []
...@@ -211,38 +199,40 @@ int Fra_NodeCompareSims( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 ) ...@@ -211,38 +199,40 @@ int Fra_NodeCompareSims( Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
unsigned Fra_NodeHashSims( Aig_Obj_t * pObj ) void Fra_CheckOutputSimsSavePattern( Fra_Man_t * p, Aig_Obj_t * pObj )
{ {
Fra_Man_t * p = pObj->pData;
static int s_FPrimes[128] = {
1009, 1049, 1093, 1151, 1201, 1249, 1297, 1361, 1427, 1459,
1499, 1559, 1607, 1657, 1709, 1759, 1823, 1877, 1933, 1997,
2039, 2089, 2141, 2213, 2269, 2311, 2371, 2411, 2467, 2543,
2609, 2663, 2699, 2741, 2797, 2851, 2909, 2969, 3037, 3089,
3169, 3221, 3299, 3331, 3389, 3461, 3517, 3557, 3613, 3671,
3719, 3779, 3847, 3907, 3943, 4013, 4073, 4129, 4201, 4243,
4289, 4363, 4441, 4493, 4549, 4621, 4663, 4729, 4793, 4871,
4933, 4973, 5021, 5087, 5153, 5227, 5281, 5351, 5417, 5471,
5519, 5573, 5651, 5693, 5749, 5821, 5861, 5923, 6011, 6073,
6131, 6199, 6257, 6301, 6353, 6397, 6481, 6563, 6619, 6689,
6737, 6803, 6863, 6917, 6977, 7027, 7109, 7187, 7237, 7309,
7393, 7477, 7523, 7561, 7607, 7681, 7727, 7817, 7877, 7933,
8011, 8039, 8059, 8081, 8093, 8111, 8123, 8147
};
unsigned * pSims; unsigned * pSims;
unsigned uHash; int i, k, BestPat, * pModel;
int i; // find the word of the pattern
assert( p->nSimWords <= 128 ); pSims = Fra_ObjSim(p->pSml, pObj->Id);
uHash = 0; for ( i = 0; i < p->pSml->nWordsTotal; i++ )
pSims = Fra_ObjSim(pObj); if ( pSims[i] )
for ( i = 0; i < p->nSimWords; i++ ) break;
uHash ^= pSims[i] * s_FPrimes[i]; assert( i < p->pSml->nWordsTotal );
return uHash; // find the bit of the pattern
for ( k = 0; k < 32; k++ )
if ( pSims[i] & (1 << k) )
break;
assert( k < 32 );
// determine the best pattern
BestPat = i * 32 + k;
// fill in the counter-example data
pModel = ALLOC( int, Aig_ManPiNum(p->pManFraig) );
Aig_ManForEachPi( p->pManAig, pObj, i )
{
pModel[i] = Aig_InfoHasBit(Fra_ObjSim(p->pSml, pObj->Id), BestPat);
// printf( "%d", pModel[i] );
}
// printf( "\n" );
// set the model
assert( p->pManFraig->pData == NULL );
p->pManFraig->pData = pModel;
return;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Simulates one node.] Synopsis [Returns 1 if the one of the output is already non-constant 0.]
Description [] Description []
...@@ -251,98 +241,30 @@ unsigned Fra_NodeHashSims( Aig_Obj_t * pObj ) ...@@ -251,98 +241,30 @@ unsigned Fra_NodeHashSims( Aig_Obj_t * pObj )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_NodeSimulate( Fra_Man_t * p, Aig_Obj_t * pObj, int iFrame ) int Fra_CheckOutputSims( Fra_Man_t * p )
{ {
unsigned * pSims, * pSims0, * pSims1; Aig_Obj_t * pObj;
int fCompl, fCompl0, fCompl1, i; int i;
int nSimWords = p->pPars->nSimWords; // make sure the reference simulation pattern does not detect the bug
assert( !Aig_IsComplement(pObj) ); pObj = Aig_ManPo( p->pManAig, 0 );
assert( Aig_ObjIsNode(pObj) ); assert( Aig_ObjFanin0(pObj)->fPhase == (unsigned)Aig_ObjFaninC0(pObj) );
assert( iFrame == 0 || nSimWords < p->nSimWords ); Aig_ManForEachPo( p->pManAig, pObj, i )
// get hold of the simulation information
pSims = Fra_ObjSim(pObj) + nSimWords * iFrame;
pSims0 = Fra_ObjSim(Aig_ObjFanin0(pObj)) + nSimWords * iFrame;
pSims1 = Fra_ObjSim(Aig_ObjFanin1(pObj)) + nSimWords * iFrame;
// get complemented attributes of the children using their random info
fCompl = pObj->fPhase;
fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj));
fCompl1 = Aig_ObjPhaseReal(Aig_ObjChild1(pObj));
// simulate
if ( fCompl0 && fCompl1 )
{
if ( fCompl )
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (pSims0[i] | pSims1[i]);
else
for ( i = 0; i < nSimWords; i++ )
pSims[i] = ~(pSims0[i] | pSims1[i]);
}
else if ( fCompl0 && !fCompl1 )
{ {
if ( fCompl ) if ( !Fra_NodeHasZeroSim( Aig_ObjFanin0(pObj) ) )
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (pSims0[i] | ~pSims1[i]);
else
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (~pSims0[i] & pSims1[i]);
}
else if ( !fCompl0 && fCompl1 )
{ {
if ( fCompl ) // create the counter-example from this pattern
for ( i = 0; i < nSimWords; i++ ) Fra_CheckOutputSimsSavePattern( p, Aig_ObjFanin0(pObj) );
pSims[i] = (~pSims0[i] | pSims1[i]); return 1;
else
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (pSims0[i] & ~pSims1[i]);
} }
else // if ( !fCompl0 && !fCompl1 )
{
if ( fCompl )
for ( i = 0; i < nSimWords; i++ )
pSims[i] = ~(pSims0[i] & pSims1[i]);
else
for ( i = 0; i < nSimWords; i++ )
pSims[i] = (pSims0[i] & pSims1[i]);
} }
return 0;
} }
/**Function*************************************************************
Synopsis [Simulates one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Fra_NodeCopyFanin( Fra_Man_t * p, Aig_Obj_t * pObj, int iFrame )
{
unsigned * pSims, * pSims0;
int fCompl, fCompl0, i;
int nSimWords = p->pPars->nSimWords;
assert( !Aig_IsComplement(pObj) );
assert( Aig_ObjIsPo(pObj) );
assert( iFrame == 0 || nSimWords < p->nSimWords );
// get hold of the simulation information
pSims = Fra_ObjSim(pObj) + nSimWords * iFrame;
pSims0 = Fra_ObjSim(Aig_ObjFanin0(pObj)) + nSimWords * iFrame;
// get complemented attributes of the children using their random info
fCompl = pObj->fPhase;
fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj));
// copy information as it is
if ( fCompl0 )
for ( i = 0; i < nSimWords; i++ )
pSims[i] = ~pSims0[i];
else
for ( i = 0; i < nSimWords; i++ )
pSims[i] = pSims0[i];
}
/**Function************************************************************* /**Function*************************************************************
Synopsis [Simulates one node.] Synopsis [Assigns random patterns to the PI node.]
Description [] Description []
...@@ -351,27 +273,19 @@ void Fra_NodeCopyFanin( Fra_Man_t * p, Aig_Obj_t * pObj, int iFrame ) ...@@ -351,27 +273,19 @@ void Fra_NodeCopyFanin( Fra_Man_t * p, Aig_Obj_t * pObj, int iFrame )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_NodeTransferNext( Fra_Man_t * p, Aig_Obj_t * pOut, Aig_Obj_t * pIn, int iFrame ) void Fra_SmlAssignRandom( Fra_Sml_t * p, Aig_Obj_t * pObj )
{ {
unsigned * pSims0, * pSims1; unsigned * pSims;
int i, nSimWords = p->pPars->nSimWords; int i;
assert( !Aig_IsComplement(pOut) ); assert( Aig_ObjIsPi(pObj) );
assert( !Aig_IsComplement(pIn) ); pSims = Fra_ObjSim( p, pObj->Id );
assert( Aig_ObjIsPo(pOut) ); for ( i = 0; i < p->nWordsTotal; i++ )
assert( Aig_ObjIsPi(pIn) ); pSims[i] = Fra_ObjRandomSim();
assert( iFrame == 0 || nSimWords < p->nSimWords );
// get hold of the simulation information
pSims0 = Fra_ObjSim(pOut) + nSimWords * iFrame;
pSims1 = Fra_ObjSim(pIn) + nSimWords * (iFrame+1);
// copy information as it is
for ( i = 0; i < nSimWords; i++ )
pSims1[i] = pSims0[i];
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Generated const 0 pattern.] Synopsis [Assigns constant patterns to the PI node.]
Description [] Description []
...@@ -380,14 +294,19 @@ void Fra_NodeTransferNext( Fra_Man_t * p, Aig_Obj_t * pOut, Aig_Obj_t * pIn, int ...@@ -380,14 +294,19 @@ void Fra_NodeTransferNext( Fra_Man_t * p, Aig_Obj_t * pOut, Aig_Obj_t * pIn, int
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_SavePattern0( Fra_Man_t * p, int fInit ) void Fra_SmlAssignConst( Fra_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame )
{ {
memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); unsigned * pSims;
int i;
assert( Aig_ObjIsPi(pObj) );
pSims = Fra_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = fConst1? ~(unsigned)0 : 0;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [[Generated const 1 pattern.] Synopsis [Assings random simulation info for the PIs.]
Description [] Description []
...@@ -396,22 +315,31 @@ void Fra_SavePattern0( Fra_Man_t * p, int fInit ) ...@@ -396,22 +315,31 @@ void Fra_SavePattern0( Fra_Man_t * p, int fInit )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_SavePattern1( Fra_Man_t * p, int fInit ) void Fra_SmlInitialize( Fra_Sml_t * p, int fInit )
{ {
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
int i, k, nTruePis; int i;
memset( p->pPatWords, 0xff, sizeof(unsigned) * p->nPatWords ); if ( fInit )
if ( !fInit ) {
return; assert( Aig_ManRegNum(p->pAig) > 0 );
nTruePis = Aig_ManPiNum(p->pManAig) - Aig_ManRegNum(p->pManAig); assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
k = 0; // assign random info for primary inputs
Aig_ManForEachLoSeq( p->pManAig, pObj, i ) Aig_ManForEachPiSeq( p->pAig, pObj, i )
Aig_InfoXorBit( p->pPatWords, nTruePis * p->nFramesAll + k++ ); Fra_SmlAssignRandom( p, pObj );
// assign the initial state for the latches
Aig_ManForEachLoSeq( p->pAig, pObj, i )
Fra_SmlAssignConst( p, pObj, 0, 0 );
}
else
{
Aig_ManForEachPi( p->pAig, pObj, i )
Fra_SmlAssignRandom( p, pObj );
}
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Copy pattern from the solver into the internal storage.] Synopsis [Assings distance-1 simulation info for the PIs.]
Description [] Description []
...@@ -420,25 +348,50 @@ void Fra_SavePattern1( Fra_Man_t * p, int fInit ) ...@@ -420,25 +348,50 @@ void Fra_SavePattern1( Fra_Man_t * p, int fInit )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_SavePattern( Fra_Man_t * p ) void Fra_SmlAssignDist1( Fra_Sml_t * p, unsigned * pPat )
{ {
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
int i; int f, i, k, Limit, nTruePis;
memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords ); assert( p->nFrames > 0 );
Aig_ManForEachPi( p->pManFraig, pObj, i ) if ( p->nFrames == 1 )
if ( p->pSat->model.ptr[Fra_ObjSatNum(pObj)] == l_True ) {
Aig_InfoSetBit( p->pPatWords, i ); // copy the PI info
Aig_ManForEachPi( p->pAig, pObj, i )
Fra_SmlAssignConst( p, pObj, Aig_InfoHasBit(pPat, i), 0 );
// flip one bit
Limit = AIG_MIN( Aig_ManPiNum(p->pAig), p->nWordsTotal * 32 - 1 );
for ( i = 0; i < Limit; i++ )
Aig_InfoXorBit( Fra_ObjSim( p, Aig_ManPi(p->pAig,i)->Id ), i+1 );
}
else
{
// copy the PI info for each frame
nTruePis = Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig);
for ( f = 0; f < p->nFrames; f++ )
Aig_ManForEachPiSeq( p->pAig, pObj, i )
Fra_SmlAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * f + i), f );
// copy the latch info
k = 0;
Aig_ManForEachLoSeq( p->pAig, pObj, i )
Fra_SmlAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * p->nFrames + k++), 0 );
// assert( p->pManFraig == NULL || nTruePis * p->nFrames + k == Aig_ManPiNum(p->pManFraig) );
/* /*
printf( "Pattern: " ); // flip one bit of the last frame
Aig_ManForEachPi( p->pManFraig, pObj, i ) if ( p->nFrames == 2 )
printf( "%d", Aig_InfoHasBit( p->pPatWords, i ) ); {
printf( "\n" ); Limit = AIG_MIN( nTruePis, p->nWordsFrame * 32 - 1 );
for ( i = 0; i < Limit; i++ )
Aig_InfoXorBit( Fra_ObjSim( p, Aig_ManPi(p->pAig, i)->Id ), i+1 );
// Aig_InfoXorBit( Fra_ObjSim( p, Aig_ManPi(p->pAig, nTruePis*(p->nFrames-2) + i)->Id ), i+1 );
}
*/ */
}
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Cleans pattern scores.] Synopsis [Simulates one node.]
Description [] Description []
...@@ -447,16 +400,63 @@ void Fra_SavePattern( Fra_Man_t * p ) ...@@ -447,16 +400,63 @@ void Fra_SavePattern( Fra_Man_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_CleanPatScores( Fra_Man_t * p ) void Fra_SmlNodeSimulate( Fra_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
{ {
int i, nLimit = p->nSimWords * 32; unsigned * pSims, * pSims0, * pSims1;
for ( i = 0; i < nLimit; i++ ) int fCompl, fCompl0, fCompl1, i;
p->pPatScores[i] = 0; assert( !Aig_IsComplement(pObj) );
assert( Aig_ObjIsNode(pObj) );
assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
// get hold of the simulation information
pSims = Fra_ObjSim(p, pObj->Id) + p->nWordsFrame * iFrame;
pSims0 = Fra_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + p->nWordsFrame * iFrame;
pSims1 = Fra_ObjSim(p, Aig_ObjFanin1(pObj)->Id) + p->nWordsFrame * iFrame;
// get complemented attributes of the children using their random info
fCompl = pObj->fPhase;
fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj));
fCompl1 = Aig_ObjPhaseReal(Aig_ObjChild1(pObj));
// simulate
if ( fCompl0 && fCompl1 )
{
if ( fCompl )
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = (pSims0[i] | pSims1[i]);
else
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = ~(pSims0[i] | pSims1[i]);
}
else if ( fCompl0 && !fCompl1 )
{
if ( fCompl )
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = (pSims0[i] | ~pSims1[i]);
else
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = (~pSims0[i] & pSims1[i]);
}
else if ( !fCompl0 && fCompl1 )
{
if ( fCompl )
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = (~pSims0[i] | pSims1[i]);
else
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = (pSims0[i] & ~pSims1[i]);
}
else // if ( !fCompl0 && !fCompl1 )
{
if ( fCompl )
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = ~(pSims0[i] & pSims1[i]);
else
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = (pSims0[i] & pSims1[i]);
}
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Adds to pattern scores.] Synopsis [Simulates one node.]
Description [] Description []
...@@ -465,65 +465,57 @@ void Fra_CleanPatScores( Fra_Man_t * p ) ...@@ -465,65 +465,57 @@ void Fra_CleanPatScores( Fra_Man_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_AddToPatScores( Fra_Man_t * p, Aig_Obj_t * pClass, Aig_Obj_t * pClassNew ) void Fra_SmlNodeCopyFanin( Fra_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
{ {
unsigned * pSims0, * pSims1; unsigned * pSims, * pSims0;
unsigned uDiff; int fCompl, fCompl0, i;
int i, w; assert( !Aig_IsComplement(pObj) );
assert( Aig_ObjIsPo(pObj) );
assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
// get hold of the simulation information // get hold of the simulation information
pSims0 = Fra_ObjSim(pClass); pSims = Fra_ObjSim(p, pObj->Id) + p->nWordsFrame * iFrame;
pSims1 = Fra_ObjSim(pClassNew); pSims0 = Fra_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + p->nWordsFrame * iFrame;
// iterate through the differences and record the score // get complemented attributes of the children using their random info
for ( w = 0; w < p->nSimWords; w++ ) fCompl = pObj->fPhase;
{ fCompl0 = Aig_ObjPhaseReal(Aig_ObjChild0(pObj));
uDiff = pSims0[w] ^ pSims1[w]; // copy information as it is
if ( uDiff == 0 ) if ( fCompl0 )
continue; for ( i = 0; i < p->nWordsFrame; i++ )
for ( i = 0; i < 32; i++ ) pSims[i] = ~pSims0[i];
if ( uDiff & ( 1 << i ) ) else
p->pPatScores[w*32+i]++; for ( i = 0; i < p->nWordsFrame; i++ )
} pSims[i] = pSims0[i];
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Selects the best pattern.] Synopsis [Simulates one node.]
Description [Returns 1 if such pattern is found.] Description []
SideEffects [] SideEffects []
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Fra_SelectBestPat( Fra_Man_t * p ) void Fra_SmlNodeTransferNext( Fra_Sml_t * p, Aig_Obj_t * pOut, Aig_Obj_t * pIn, int iFrame )
{ {
unsigned * pSims; unsigned * pSims0, * pSims1;
Aig_Obj_t * pObj; int i;
int i, nLimit = p->nSimWords * 32, MaxScore = 0, BestPat = -1; assert( !Aig_IsComplement(pOut) );
for ( i = 1; i < nLimit; i++ ) assert( !Aig_IsComplement(pIn) );
{ assert( Aig_ObjIsPo(pOut) );
if ( MaxScore < p->pPatScores[i] ) assert( Aig_ObjIsPi(pIn) );
{ assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
MaxScore = p->pPatScores[i]; // get hold of the simulation information
BestPat = i; pSims0 = Fra_ObjSim(p, pOut->Id) + p->nWordsFrame * iFrame;
} pSims1 = Fra_ObjSim(p, pIn->Id) + p->nWordsFrame * (iFrame+1);
} // copy information as it is
if ( MaxScore == 0 ) for ( i = 0; i < p->nWordsFrame; i++ )
return 0; pSims1[i] = pSims0[i];
// if ( MaxScore > p->pPars->MaxScore )
// printf( "Max score is %3d. ", MaxScore );
// copy the best pattern into the selected pattern
memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
Aig_ManForEachPi( p->pManAig, pObj, i )
{
pSims = Fra_ObjSim(pObj);
if ( Aig_InfoHasBit(pSims, BestPat) )
Aig_InfoSetBit(p->pPatWords, i);
}
return MaxScore;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Simulates AIG manager.] Synopsis [Simulates AIG manager.]
...@@ -535,31 +527,32 @@ int Fra_SelectBestPat( Fra_Man_t * p ) ...@@ -535,31 +527,32 @@ int Fra_SelectBestPat( Fra_Man_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_SimulateOne( Fra_Man_t * p ) void Fra_SmlSimulateOne( Fra_Sml_t * p )
{ {
Aig_Obj_t * pObj, * pObjLi, * pObjLo; Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int f, i, clk; int f, i, clk;
clk = clock(); clk = clock();
for ( f = 0; f < p->nFramesAll; f++ ) for ( f = 0; f < p->nFrames; f++ )
{ {
// simulate the nodes // simulate the nodes
Aig_ManForEachNode( p->pManAig, pObj, i ) Aig_ManForEachNode( p->pAig, pObj, i )
Fra_NodeSimulate( p, pObj, f ); Fra_SmlNodeSimulate( p, pObj, f );
if ( f == p->nFramesAll - 1 ) if ( f == p->nFrames - 1 )
break; break;
// copy simulation info into outputs // copy simulation info into outputs
Aig_ManForEachLiSeq( p->pManAig, pObj, i ) Aig_ManForEachLiSeq( p->pAig, pObj, i )
Fra_NodeCopyFanin( p, pObj, f ); Fra_SmlNodeCopyFanin( p, pObj, f );
// copy simulation info into the inputs // copy simulation info into the inputs
// for ( i = 0; i < Aig_ManRegNum(p->pManAig); i++ ) // for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ )
// Fra_NodeTransferNext( p, Aig_ManLi(p->pManAig, i), Aig_ManLo(p->pManAig, i), f ); // Fra_SmlNodeTransferNext( p, Aig_ManLi(p->pAig, i), Aig_ManLo(p->pAig, i), f );
Aig_ManForEachLiLoSeq( p->pManAig, pObjLi, pObjLo, i ) Aig_ManForEachLiLoSeq( p->pAig, pObjLi, pObjLo, i )
Fra_NodeTransferNext( p, pObjLi, pObjLo, f ); Fra_SmlNodeTransferNext( p, pObjLi, pObjLo, f );
} }
p->timeSim += clock() - clk; p->timeSim += clock() - clk;
p->nSimRounds++; p->nSimRounds++;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Resimulates fraiging manager after finding a counter-example.] Synopsis [Resimulates fraiging manager after finding a counter-example.]
...@@ -571,43 +564,25 @@ p->nSimRounds++; ...@@ -571,43 +564,25 @@ p->nSimRounds++;
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_Resimulate( Fra_Man_t * p ) void Fra_SmlResimulate( Fra_Man_t * p )
{ {
int nChanges, clk; int nChanges, clk;
Fra_AssignDist1( p, p->pPatWords ); Fra_SmlAssignDist1( p->pSml, p->pPatWords );
Fra_SimulateOne( p ); Fra_SmlSimulateOne( p->pSml );
if ( p->pPars->fPatScores ) // if ( p->pPars->fPatScores )
Fra_CleanPatScores( p ); // Fra_CleanPatScores( p );
if ( p->pPars->fProve && Fra_CheckOutputSims(p) ) if ( p->pPars->fProve && Fra_CheckOutputSims(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 );
if ( p->pCla->vImps )
nChanges += Fra_ImpRefineUsingCex( p, p->pCla->vImps );
p->timeRef += clock() - clk; p->timeRef += clock() - clk;
if ( nChanges < 1 ) if ( nChanges < 1 )
printf( "Error: A counter-example did not refine classes!\n" ); printf( "Error: A counter-example did not refine classes!\n" );
assert( nChanges >= 1 ); assert( nChanges >= 1 );
//printf( "Refined classes = %5d. Changes = %4d.\n", Vec_PtrSize(p->vClasses), nChanges ); //printf( "Refined classes = %5d. Changes = %4d.\n", Vec_PtrSize(p->vClasses), nChanges );
if ( !p->pPars->fPatScores )
return;
// perform additional simulation using dist1 patterns derived from successful patterns
while ( Fra_SelectBestPat(p) > p->pPars->MaxScore )
{
Fra_AssignDist1( p, p->pPatWords );
Fra_SimulateOne( p );
Fra_CleanPatScores( p );
if ( p->pPars->fProve && Fra_CheckOutputSims(p) )
return;
clk = clock();
nChanges = Fra_ClassesRefine( p->pCla );
nChanges += Fra_ClassesRefine1( p->pCla );
p->timeRef += clock() - clk;
//printf( "Refined class!!! = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Fra_CountPairsClasses(p) );
if ( nChanges == 0 )
break;
}
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -621,31 +596,34 @@ p->timeRef += clock() - clk; ...@@ -621,31 +596,34 @@ p->timeRef += clock() - clk;
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_Simulate( Fra_Man_t * p, int fInit ) void Fra_SmlSimulate( Fra_Man_t * p, int fInit )
{ {
int fVerbose = 0;
int nChanges, nClasses, clk; int nChanges, nClasses, clk;
assert( !fInit || Aig_ManRegNum(p->pManAig) ); assert( !fInit || Aig_ManRegNum(p->pManAig) );
// start the classes // start the classes
Fra_AssignRandom( p, fInit ); Fra_SmlInitialize( p->pSml, fInit );
Fra_SimulateOne( p ); Fra_SmlSimulateOne( p->pSml );
Fra_ClassesPrepare( p->pCla, p->pPars->fLatchCorr ); Fra_ClassesPrepare( p->pCla, p->pPars->fLatchCorr );
// Fra_ClassesPrint( p->pCla, 0 ); // Fra_ClassesPrint( p->pCla, 0 );
//printf( "Starting classes = %5d. Pairs = %6d.\n", p->lClasses.nItems, Fra_CountPairsClasses(p) ); if ( fVerbose )
printf( "Starting classes = %5d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses), Fra_ClassesCountLits(p->pCla) );
// refine classes by walking 0/1 patterns // refine classes by walking 0/1 patterns
Fra_SavePattern0( p, fInit ); Fra_SavePattern0( p, fInit );
Fra_AssignDist1( p, p->pPatWords ); Fra_SmlAssignDist1( p->pSml, p->pPatWords );
Fra_SimulateOne( p ); Fra_SmlSimulateOne( p->pSml );
if ( p->pPars->fProve && Fra_CheckOutputSims(p) ) if ( p->pPars->fProve && Fra_CheckOutputSims(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 );
p->timeRef += clock() - clk; p->timeRef += clock() - clk;
//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Fra_CountPairsClasses(p) ); if ( fVerbose )
printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses), nChanges, Fra_ClassesCountLits(p->pCla) );
Fra_SavePattern1( p, fInit ); Fra_SavePattern1( p, fInit );
Fra_AssignDist1( p, p->pPatWords ); Fra_SmlAssignDist1( p->pSml, p->pPatWords );
Fra_SimulateOne( p ); Fra_SmlSimulateOne( p->pSml );
if ( p->pPars->fProve && Fra_CheckOutputSims(p) ) if ( p->pPars->fProve && Fra_CheckOutputSims(p) )
return; return;
clk = clock(); clk = clock();
...@@ -653,11 +631,12 @@ clk = clock(); ...@@ -653,11 +631,12 @@ clk = clock();
nChanges += Fra_ClassesRefine1( p->pCla ); nChanges += Fra_ClassesRefine1( p->pCla );
p->timeRef += clock() - clk; p->timeRef += clock() - clk;
//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Fra_CountPairsClasses(p) ); if ( fVerbose )
printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses), nChanges, Fra_ClassesCountLits(p->pCla) );
// refine classes by random simulation // refine classes by random simulation
do { do {
Fra_AssignRandom( p, fInit ); Fra_SmlInitialize( p->pSml, fInit );
Fra_SimulateOne( p ); Fra_SmlSimulateOne( p->pSml );
nClasses = Vec_PtrSize(p->pCla->vClasses); nClasses = Vec_PtrSize(p->pCla->vClasses);
if ( p->pPars->fProve && Fra_CheckOutputSims(p) ) if ( p->pPars->fProve && Fra_CheckOutputSims(p) )
return; return;
...@@ -665,19 +644,20 @@ clk = clock(); ...@@ -665,19 +644,20 @@ clk = clock();
nChanges = Fra_ClassesRefine( p->pCla ); nChanges = Fra_ClassesRefine( p->pCla );
nChanges += Fra_ClassesRefine1( p->pCla ); nChanges += Fra_ClassesRefine1( p->pCla );
p->timeRef += clock() - clk; p->timeRef += clock() - clk;
//printf( "Refined classes = %5d. Changes = %4d. Pairs = %6d.\n", p->lClasses.nItems, nChanges, Fra_CountPairsClasses(p) ); if ( fVerbose )
printf( "Refined classes = %5d. Changes = %4d. Lits = %6d.\n", Vec_PtrSize(p->pCla->vClasses), nChanges, Fra_ClassesCountLits(p->pCla) );
} while ( (double)nChanges / nClasses > p->pPars->dSimSatur ); } while ( (double)nChanges / nClasses > p->pPars->dSimSatur );
// if ( p->pPars->fVerbose ) // if ( p->pPars->fVerbose )
// printf( "Consts = %6d. Classes = %6d. Literals = %6d.\n", // printf( "Consts = %6d. Classes = %6d. Literals = %6d.\n",
// Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses), Fra_ClassesCountLits(p->pCla) ); // Vec_PtrSize(p->pCla->vClasses1), Vec_PtrSize(p->pCla->vClasses), Fra_ClassesCountLits(p->pCla) );
// Fra_ClassesPrint( p->pCla, 0 ); // Fra_ClassesPrint( p->pCla, 0 );
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Creates the counter-example from the successful pattern.] Synopsis [Allocates simulation manager.]
Description [] Description []
...@@ -686,40 +666,22 @@ p->timeRef += clock() - clk; ...@@ -686,40 +666,22 @@ p->timeRef += clock() - clk;
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Fra_CheckOutputSimsSavePattern( Fra_Man_t * p, Aig_Obj_t * pObj ) Fra_Sml_t * Fra_SmlStart( Aig_Man_t * pAig, int nFrames, int nWordsFrame )
{ {
unsigned * pSims; Fra_Sml_t * p;
int i, k, BestPat, * pModel; assert( Aig_ManObjIdMax(pAig) + 1 < (1 << 16) );
// find the word of the pattern p = (Fra_Sml_t *)malloc( sizeof(Fra_Sml_t) + sizeof(unsigned) * (Aig_ManObjIdMax(pAig) + 1) * nFrames * nWordsFrame );
pSims = Fra_ObjSim(pObj); memset( p, 0, sizeof(Fra_Sml_t) + sizeof(unsigned) * nFrames * nWordsFrame );
for ( i = 0; i < p->nSimWords; i++ ) p->pAig = pAig;
if ( pSims[i] ) p->nFrames = nFrames;
break; p->nWordsFrame = nWordsFrame;
assert( i < p->nSimWords ); p->nWordsTotal = nFrames * nWordsFrame;
// find the bit of the pattern return p;
for ( k = 0; k < 32; k++ )
if ( pSims[i] & (1 << k) )
break;
assert( k < 32 );
// determine the best pattern
BestPat = i * 32 + k;
// fill in the counter-example data
pModel = ALLOC( int, Aig_ManPiNum(p->pManFraig) );
Aig_ManForEachPi( p->pManAig, pObj, i )
{
pModel[i] = Aig_InfoHasBit(Fra_ObjSim(pObj), BestPat);
// printf( "%d", pModel[i] );
}
// printf( "\n" );
// set the model
assert( p->pManFraig->pData == NULL );
p->pManFraig->pData = pModel;
return;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [Returns 1 if the one of the output is already non-constant 0.] Synopsis [Deallocates simulation manager.]
Description [] Description []
...@@ -728,26 +690,52 @@ void Fra_CheckOutputSimsSavePattern( Fra_Man_t * p, Aig_Obj_t * pObj ) ...@@ -728,26 +690,52 @@ void Fra_CheckOutputSimsSavePattern( Fra_Man_t * p, Aig_Obj_t * pObj )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Fra_CheckOutputSims( Fra_Man_t * p ) void Fra_SmlStop( Fra_Sml_t * p )
{ {
Aig_Obj_t * pObj; free( p );
int i;
// make sure the reference simulation pattern does not detect the bug
pObj = Aig_ManPo( p->pManAig, 0 );
assert( Aig_ObjFanin0(pObj)->fPhase == (unsigned)Aig_ObjFaninC0(pObj) );
Aig_ManForEachPo( p->pManAig, pObj, i )
{
if ( !Fra_NodeHasZeroSim( Aig_ObjFanin0(pObj) ) )
{
// create the counter-example from this pattern
Fra_CheckOutputSimsSavePattern( p, Aig_ObjFanin0(pObj) );
return 1;
}
}
return 0;
} }
/**Function*************************************************************
Synopsis [Performs simulation of the uninitialized circuit.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Fra_Sml_t * Fra_SmlSimulateComb( Aig_Man_t * pAig, int nWords )
{
Fra_Sml_t * p;
p = Fra_SmlStart( pAig, 1, nWords );
Fra_SmlInitialize( p, 0 );
Fra_SmlSimulateOne( p );
return p;
}
/**Function*************************************************************
Synopsis [Performs simulation of the initialized circuit.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Fra_Sml_t * Fra_SmlSimulateSeq( Aig_Man_t * pAig, int nFrames, int nWords )
{
Fra_Sml_t * p;
p = Fra_SmlStart( pAig, nFrames, nWords );
Fra_SmlInitialize( p, 1 );
Fra_SmlSimulateOne( p );
return p;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -10974,11 +10974,11 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -10974,11 +10974,11 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
int c; int c;
int nFramesK; int nFramesK;
int fExdc; int fExdc;
int fImp; int fUseImps;
int fRewrite; int fRewrite;
int fLatchCorr; int fLatchCorr;
int fVerbose; int fVerbose;
extern Abc_Ntk_t * Abc_NtkSeqSweep( Abc_Ntk_t * pNtk, int nFrames, int fRewrite, int fLatchCorr, int fVerbose ); extern Abc_Ntk_t * Abc_NtkSeqSweep( Abc_Ntk_t * pNtk, int nFrames, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose );
pNtk = Abc_FrameReadNtk(pAbc); pNtk = Abc_FrameReadNtk(pAbc);
pOut = Abc_FrameReadOut(pAbc); pOut = Abc_FrameReadOut(pAbc);
...@@ -10987,7 +10987,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -10987,7 +10987,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults // set defaults
nFramesK = 1; nFramesK = 1;
fExdc = 1; fExdc = 1;
fImp = 0; fUseImps = 0;
fRewrite = 0; fRewrite = 0;
fLatchCorr = 0; fLatchCorr = 0;
fVerbose = 0; fVerbose = 0;
...@@ -11011,7 +11011,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11011,7 +11011,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
fExdc ^= 1; fExdc ^= 1;
break; break;
case 'i': case 'i':
fImp ^= 1; fUseImps ^= 1;
break; break;
case 'r': case 'r':
fRewrite ^= 1; fRewrite ^= 1;
...@@ -11048,7 +11048,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11048,7 +11048,7 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
} }
// get the new network // get the new network
pNtkRes = Abc_NtkSeqSweep( pNtk, nFramesK, fRewrite, fLatchCorr, fVerbose ); pNtkRes = Abc_NtkSeqSweep( pNtk, nFramesK, fRewrite, fUseImps, fLatchCorr, fVerbose );
if ( pNtkRes == NULL ) if ( pNtkRes == NULL )
{ {
fprintf( pErr, "Sequential sweeping has failed.\n" ); fprintf( pErr, "Sequential sweeping has failed.\n" );
...@@ -11059,11 +11059,11 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -11059,11 +11059,11 @@ int Abc_CommandSeqSweep( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: usage:
fprintf( pErr, "usage: ssweep [-F num] [-lrvh]\n" ); fprintf( pErr, "usage: ssweep [-F num] [-ilrvh]\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-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-e : toggle writing EXDC network [default = %s]\n", fExdc? "yes": "no" ); // fprintf( pErr, "\t-e : toggle writing EXDC network [default = %s]\n", fExdc? "yes": "no" );
// fprintf( pErr, "\t-i : toggle computing implications [default = %s]\n", fImp? "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-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", fVerbose? "yes": "no" );
......
...@@ -892,16 +892,26 @@ int Abc_NtkDSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fVer ...@@ -892,16 +892,26 @@ int Abc_NtkDSat( Abc_Ntk_t * pNtk, sint64 nConfLimit, sint64 nInsLimit, int fVer
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Abc_Ntk_t * Abc_NtkSeqSweep( Abc_Ntk_t * pNtk, int nFramesK, int fRewrite, int fLatchCorr, int fVerbose ) Abc_Ntk_t * Abc_NtkSeqSweep( Abc_Ntk_t * pNtk, int nFramesK, int fRewrite, int fUseImps, int fLatchCorr, int fVerbose )
{ {
Abc_Ntk_t * pNtkAig; Fraig_Params_t Params;
Abc_Ntk_t * pNtkAig, * pNtkFraig;
Aig_Man_t * pMan, * pTemp; Aig_Man_t * pMan, * pTemp;
pMan = Abc_NtkToDar( pNtk, 1 );
// preprocess the miter by fraiging it
// (note that for each functional class, fraiging leaves one representative;
// so fraiging does not reduce the number of functions represented by nodes
Fraig_ParamsSetDefault( &Params );
Params.nBTLimit = 100000;
pNtkFraig = Abc_NtkFraig( pNtk, &Params, 0, 0 );
// pNtkFraig = Abc_NtkDup( pNtk );
pMan = Abc_NtkToDar( pNtkFraig, 1 );
Abc_NtkDelete( pNtkFraig );
if ( pMan == NULL ) if ( pMan == NULL )
return NULL; return NULL;
// pMan->nRegs = Abc_NtkLatchNum(pNtk);
pMan = Fra_FraigInduction( pTemp = pMan, nFramesK, fRewrite, fLatchCorr, fVerbose, NULL ); pMan = Fra_FraigInduction( pTemp = pMan, nFramesK, fRewrite, fUseImps, fLatchCorr, fVerbose, NULL );
Aig_ManStop( pTemp ); Aig_ManStop( pTemp );
if ( Aig_ManRegNum(pMan) < Abc_NtkLatchNum(pNtk) ) if ( Aig_ManRegNum(pMan) < Abc_NtkLatchNum(pNtk) )
...@@ -960,6 +970,7 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo ...@@ -960,6 +970,7 @@ int Abc_NtkDarSec( Abc_Ntk_t * pNtk1, Abc_Ntk_t * pNtk2, int nFrames, int fVerbo
// (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
Fraig_ParamsSetDefault( &Params ); Fraig_ParamsSetDefault( &Params );
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 );
......
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