Commit e917dda1 by Alan Mishchenko

Version abc81013

parent a2535d49
...@@ -3298,6 +3298,10 @@ SOURCE=.\src\aig\saig\saigHaig.c ...@@ -3298,6 +3298,10 @@ SOURCE=.\src\aig\saig\saigHaig.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\aig\saig\saigInd.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\saig\saigIoa.c SOURCE=.\src\aig\saig\saigIoa.c
# End Source File # End Source File
# Begin Source File # Begin Source File
...@@ -3494,6 +3498,10 @@ SOURCE=.\src\aig\ssw\sswSat.c ...@@ -3494,6 +3498,10 @@ SOURCE=.\src\aig\ssw\sswSat.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\src\aig\ssw\sswSemi.c
# End Source File
# Begin Source File
SOURCE=.\src\aig\ssw\sswSim.c SOURCE=.\src\aig\ssw\sswSim.c
# End Source File # End Source File
# Begin Source File # Begin Source File
......
...@@ -654,6 +654,8 @@ extern void Aig_ManCleanPioNumbers( Aig_Man_t * p ); ...@@ -654,6 +654,8 @@ extern void Aig_ManCleanPioNumbers( Aig_Man_t * p );
extern int Aig_ManCountChoices( Aig_Man_t * p ); extern int Aig_ManCountChoices( Aig_Man_t * p );
extern char * Aig_FileNameGenericAppend( char * pBase, char * pSuffix ); extern char * Aig_FileNameGenericAppend( char * pBase, char * pSuffix );
extern unsigned Aig_ManRandom( int fReset ); extern unsigned Aig_ManRandom( int fReset );
extern void Aig_NodeUnionLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr );
extern void Aig_NodeIntersectLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr );
/*=== aigWin.c =========================================================*/ /*=== aigWin.c =========================================================*/
extern void Aig_ManFindCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVisited, int nSizeLimit, int nFanoutLimit ); extern void Aig_ManFindCut( Aig_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVisited, int nSizeLimit, int nFanoutLimit );
......
...@@ -1122,6 +1122,86 @@ unsigned Aig_ManRandom( int fReset ) ...@@ -1122,6 +1122,86 @@ unsigned Aig_ManRandom( int fReset )
} }
/**Function*************************************************************
Synopsis [Returns the result of merging the two vectors.]
Description [Assumes that the vectors are sorted in the increasing order.]
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodeUnionLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr )
{
Aig_Obj_t ** pBeg = (Aig_Obj_t **)vArr->pArray;
Aig_Obj_t ** pBeg1 = (Aig_Obj_t **)vArr1->pArray;
Aig_Obj_t ** pBeg2 = (Aig_Obj_t **)vArr2->pArray;
Aig_Obj_t ** pEnd1 = (Aig_Obj_t **)vArr1->pArray + vArr1->nSize;
Aig_Obj_t ** pEnd2 = (Aig_Obj_t **)vArr2->pArray + vArr2->nSize;
Vec_PtrGrow( vArr, Vec_PtrSize(vArr1) + Vec_PtrSize(vArr2) );
pBeg = (Aig_Obj_t **)vArr->pArray;
while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
{
if ( (*pBeg1)->Id == (*pBeg2)->Id )
*pBeg++ = *pBeg1++, pBeg2++;
else if ( (*pBeg1)->Id < (*pBeg2)->Id )
*pBeg++ = *pBeg1++;
else
*pBeg++ = *pBeg2++;
}
while ( pBeg1 < pEnd1 )
*pBeg++ = *pBeg1++;
while ( pBeg2 < pEnd2 )
*pBeg++ = *pBeg2++;
vArr->nSize = pBeg - (Aig_Obj_t **)vArr->pArray;
assert( vArr->nSize <= vArr->nCap );
assert( vArr->nSize >= vArr1->nSize );
assert( vArr->nSize >= vArr2->nSize );
}
/**Function*************************************************************
Synopsis [Returns the result of intersecting the two vectors.]
Description [Assumes that the vectors are sorted in the increasing order.]
SideEffects []
SeeAlso []
***********************************************************************/
void Aig_NodeIntersectLists( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr )
{
Aig_Obj_t ** pBeg = (Aig_Obj_t **)vArr->pArray;
Aig_Obj_t ** pBeg1 = (Aig_Obj_t **)vArr1->pArray;
Aig_Obj_t ** pBeg2 = (Aig_Obj_t **)vArr2->pArray;
Aig_Obj_t ** pEnd1 = (Aig_Obj_t **)vArr1->pArray + vArr1->nSize;
Aig_Obj_t ** pEnd2 = (Aig_Obj_t **)vArr2->pArray + vArr2->nSize;
Vec_PtrGrow( vArr, AIG_MAX( Vec_PtrSize(vArr1), Vec_PtrSize(vArr2) ) );
pBeg = (Aig_Obj_t **)vArr->pArray;
while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
{
if ( (*pBeg1)->Id == (*pBeg2)->Id )
*pBeg++ = *pBeg1++, pBeg2++;
else if ( (*pBeg1)->Id < (*pBeg2)->Id )
// *pBeg++ = *pBeg1++;
pBeg1++;
else
// *pBeg++ = *pBeg2++;
pBeg2++;
}
// while ( pBeg1 < pEnd1 )
// *pBeg++ = *pBeg1++;
// while ( pBeg2 < pEnd2 )
// *pBeg++ = *pBeg2++;
vArr->nSize = pBeg - (Aig_Obj_t **)vArr->pArray;
assert( vArr->nSize <= vArr->nCap );
assert( vArr->nSize <= vArr1->nSize );
assert( vArr->nSize <= vArr2->nSize );
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -3,6 +3,7 @@ SRC += src/aig/saig/saigAbs.c \ ...@@ -3,6 +3,7 @@ SRC += src/aig/saig/saigAbs.c \
src/aig/saig/saigCone.c \ src/aig/saig/saigCone.c \
src/aig/saig/saigDup.c \ src/aig/saig/saigDup.c \
src/aig/saig/saigHaig.c \ src/aig/saig/saigHaig.c \
src/aig/saig/saigInd.c \
src/aig/saig/saigIoa.c \ src/aig/saig/saigIoa.c \
src/aig/saig/saigLoc.c \ src/aig/saig/saigLoc.c \
src/aig/saig/saigMiter.c \ src/aig/saig/saigMiter.c \
......
...@@ -87,6 +87,8 @@ extern Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * p ); ...@@ -87,6 +87,8 @@ extern Aig_Man_t * Said_ManDupOrpos( Aig_Man_t * p );
extern Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * pAig, Vec_Int_t * vFlops ); extern Aig_Man_t * Saig_ManAbstraction( Aig_Man_t * pAig, Vec_Int_t * vFlops );
/*=== saigHaig.c ==========================================================*/ /*=== saigHaig.c ==========================================================*/
extern Aig_Man_t * Saig_ManHaigRecord( Aig_Man_t * p, int nIters, int nSteps, int fRetimingOnly, int fAddBugs, int fUseCnf, int fVerbose ); extern Aig_Man_t * Saig_ManHaigRecord( Aig_Man_t * p, int nIters, int nSteps, int fRetimingOnly, int fAddBugs, int fUseCnf, int fVerbose );
/*=== saigInd.c ==========================================================*/
extern int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose );
/*=== saigIoa.c ==========================================================*/ /*=== saigIoa.c ==========================================================*/
extern void Saig_ManDumpBlif( Aig_Man_t * p, char * pFileName ); extern void Saig_ManDumpBlif( Aig_Man_t * p, char * pFileName );
extern Aig_Man_t * Saig_ManReadBlif( char * pFileName ); extern Aig_Man_t * Saig_ManReadBlif( char * pFileName );
......
...@@ -51,7 +51,7 @@ Aig_Man_t * Saig_ManFramesBmcLast( Aig_Man_t * pAig, int nFrames, Aig_Obj_t *** ...@@ -51,7 +51,7 @@ Aig_Man_t * Saig_ManFramesBmcLast( Aig_Man_t * pAig, int nFrames, Aig_Obj_t ***
{ {
Aig_Man_t * pFrames; Aig_Man_t * pFrames;
Aig_Obj_t ** ppMap; Aig_Obj_t ** ppMap;
Aig_Obj_t * pObj, * pObjLi, * pObjLo; Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pResult;
int i, f; int i, f;
assert( Saig_ManRegNum(pAig) > 0 ); assert( Saig_ManRegNum(pAig) > 0 );
// start the mapping // start the mapping
...@@ -61,10 +61,12 @@ Aig_Man_t * Saig_ManFramesBmcLast( Aig_Man_t * pAig, int nFrames, Aig_Obj_t *** ...@@ -61,10 +61,12 @@ Aig_Man_t * Saig_ManFramesBmcLast( Aig_Man_t * pAig, int nFrames, Aig_Obj_t ***
// create variables for register outputs // create variables for register outputs
Saig_ManForEachLo( pAig, pObj, i ) Saig_ManForEachLo( pAig, pObj, i )
{ {
pObj->pData = Aig_ManConst0( pFrames ); // pObj->pData = Aig_ManConst0( pFrames );
pObj->pData = Aig_ObjCreatePi( pFrames );
Saig_ObjSetFrame( ppMap, nFrames, pObj, 0, pObj->pData ); Saig_ObjSetFrame( ppMap, nFrames, pObj, 0, pObj->pData );
} }
// add timeframes // add timeframes
pResult = Aig_ManConst0(pFrames);
for ( f = 0; f < nFrames; f++ ) for ( f = 0; f < nFrames; f++ )
{ {
// map the constant node // map the constant node
...@@ -82,14 +84,17 @@ Aig_Man_t * Saig_ManFramesBmcLast( Aig_Man_t * pAig, int nFrames, Aig_Obj_t *** ...@@ -82,14 +84,17 @@ Aig_Man_t * Saig_ManFramesBmcLast( Aig_Man_t * pAig, int nFrames, Aig_Obj_t ***
pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) ); pObj->pData = Aig_And( pFrames, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
Saig_ObjSetFrame( ppMap, nFrames, pObj, f, pObj->pData ); Saig_ObjSetFrame( ppMap, nFrames, pObj, f, pObj->pData );
} }
// OR the POs
Saig_ManForEachPo( pAig, pObj, i )
pResult = Aig_Or( pFrames, pResult, Aig_ObjChild0Copy(pObj) );
// create POs for this frame // create POs for this frame
if ( f == nFrames - 1 ) if ( f == nFrames - 1 )
{ {
Saig_ManForEachPo( pAig, pObj, i ) // Saig_ManForEachPo( pAig, pObj, i )
{ // {
pObj->pData = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) ); // pObj->pData = Aig_ObjCreatePo( pFrames, Aig_ObjChild0Copy(pObj) );
Saig_ObjSetFrame( ppMap, nFrames, pObj, f, pObj->pData ); // Saig_ObjSetFrame( ppMap, nFrames, pObj, f, pObj->pData );
} // }
break; break;
} }
// save register inputs // save register inputs
...@@ -105,6 +110,7 @@ Aig_Man_t * Saig_ManFramesBmcLast( Aig_Man_t * pAig, int nFrames, Aig_Obj_t *** ...@@ -105,6 +110,7 @@ Aig_Man_t * Saig_ManFramesBmcLast( Aig_Man_t * pAig, int nFrames, Aig_Obj_t ***
Saig_ObjSetFrame( ppMap, nFrames, pObjLo, f, pObjLo->pData ); Saig_ObjSetFrame( ppMap, nFrames, pObjLo, f, pObjLo->pData );
} }
} }
Aig_ObjCreatePo( pFrames, pResult );
Aig_ManCleanup( pFrames ); Aig_ManCleanup( pFrames );
// remove mapping for the nodes that are no longer there // remove mapping for the nodes that are no longer there
for ( i = 0; i < Aig_ManObjNumMax(pAig) * nFrames; i++ ) for ( i = 0; i < Aig_ManObjNumMax(pAig) * nFrames; i++ )
...@@ -124,14 +130,15 @@ Aig_Man_t * Saig_ManFramesBmcLast( Aig_Man_t * pAig, int nFrames, Aig_Obj_t *** ...@@ -124,14 +130,15 @@ Aig_Man_t * Saig_ManFramesBmcLast( Aig_Man_t * pAig, int nFrames, Aig_Obj_t ***
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int * Saig_ManFindUnsatVariables( Cnf_Dat_t * pCnf, int nConfMax, int fVerbose ) int * Saig_ManFindUnsatVariables( Cnf_Dat_t * pCnf, int nRegs, int nConfMax, int fVerbose )
{ {
void * pSatCnf; void * pSatCnf;
Intp_Man_t * pManProof; Intp_Man_t * pManProof;
Aig_Obj_t * pObj;
sat_solver * pSat; sat_solver * pSat;
Vec_Int_t * vCore; Vec_Int_t * vCore;
int * pClause1, * pClause2, * pLit, * pVars, iClause, nVars; int * pClause1, * pClause2, * pLit, * pVars, iClause, nVars;
int i, RetValue; int i, Lit, RetValue;
// create the SAT solver // create the SAT solver
pSat = sat_solver_new(); pSat = sat_solver_new();
sat_solver_store_alloc( pSat ); sat_solver_store_alloc( pSat );
...@@ -145,6 +152,15 @@ int * Saig_ManFindUnsatVariables( Cnf_Dat_t * pCnf, int nConfMax, int fVerbose ) ...@@ -145,6 +152,15 @@ int * Saig_ManFindUnsatVariables( Cnf_Dat_t * pCnf, int nConfMax, int fVerbose )
return NULL; return NULL;
} }
} }
Aig_ManForEachPi( pCnf->pMan, pObj, i )
{
if ( i == nRegs )
break;
assert( pCnf->pVarNums[pObj->Id] >= 0 );
Lit = toLitCond( pCnf->pVarNums[pObj->Id], 1 );
if ( !sat_solver_addclause( pSat, &Lit, &Lit+1 ) )
assert( 0 );
}
sat_solver_store_mark_roots( pSat ); sat_solver_store_mark_roots( pSat );
// solve the problem // solve the problem
RetValue = sat_solver_solve( pSat, NULL, NULL, (sint64)nConfMax, (sint64)0, (sint64)0, (sint64)0 ); RetValue = sat_solver_solve( pSat, NULL, NULL, (sint64)nConfMax, (sint64)0, (sint64)0, (sint64)0 );
...@@ -240,11 +256,12 @@ Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax, ...@@ -240,11 +256,12 @@ Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax,
printf( "Performing proof-based abstraction with %d frames and %d max conflicts.\n", nFrames, nConfMax ); printf( "Performing proof-based abstraction with %d frames and %d max conflicts.\n", nFrames, nConfMax );
// create the timeframes // create the timeframes
pFrames = Saig_ManFramesBmcLast( p, nFrames, &ppAigToFrames ); pFrames = Saig_ManFramesBmcLast( p, nFrames, &ppAigToFrames );
printf( "AIG nodes = %d. Frames = %d.\n", Aig_ManNodeNum(p), Aig_ManNodeNum(pFrames) );
// convert them into CNF // convert them into CNF
// pCnf = Cnf_Derive( pFrames, 0 ); // pCnf = Cnf_Derive( pFrames, 0 );
pCnf = Cnf_DeriveSimple( pFrames, 0 ); pCnf = Cnf_DeriveSimple( pFrames, 0 );
// collect CNF variables involved in UNSAT core // collect CNF variables involved in UNSAT core
pUnsatCoreVars = Saig_ManFindUnsatVariables( pCnf, nConfMax, 0 ); pUnsatCoreVars = Saig_ManFindUnsatVariables( pCnf, Saig_ManRegNum(p), nConfMax, 0 );
if ( pUnsatCoreVars == NULL ) if ( pUnsatCoreVars == NULL )
{ {
Aig_ManStop( pFrames ); Aig_ManStop( pFrames );
......
...@@ -249,8 +249,10 @@ int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLim ...@@ -249,8 +249,10 @@ int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLim
{ {
Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 ); Lit = toLitCond( pCnf->pVarNums[pObj->Id], 0 );
if ( fVerbose ) if ( fVerbose )
{
printf( "Solving output %2d of frame %3d ... \r", printf( "Solving output %2d of frame %3d ... \r",
i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) );
}
clk = clock(); clk = clock();
status = sat_solver_solve( pSat, &Lit, &Lit + 1, (sint64)nConfLimit, (sint64)0, (sint64)0, (sint64)0 ); status = sat_solver_solve( pSat, &Lit, &Lit + 1, (sint64)nConfLimit, (sint64)0, (sint64)0, (sint64)0 );
if ( fVerbose && (i % Saig_ManPoNum(pAig) == Saig_ManPoNum(pAig) - 1) ) if ( fVerbose && (i % Saig_ManPoNum(pAig) == Saig_ManPoNum(pAig) - 1) )
...@@ -258,12 +260,22 @@ int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLim ...@@ -258,12 +260,22 @@ int Saig_ManBmcSimple( Aig_Man_t * pAig, int nFrames, int nSizeMax, int nConfLim
printf( "Solved %2d outputs of frame %3d. ", printf( "Solved %2d outputs of frame %3d. ",
Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) ); Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) );
printf( "Conf =%8.0f. Imp =%11.0f. ", (double)pSat->stats.conflicts, (double)pSat->stats.propagations ); printf( "Conf =%8.0f. Imp =%11.0f. ", (double)pSat->stats.conflicts, (double)pSat->stats.propagations );
PRT( "Time", clock() - clkPart ); PRT( "T", clock() - clkPart );
clkPart = clock(); clkPart = clock();
fflush( stdout ); fflush( stdout );
} }
if ( status == l_False ) if ( status == l_False )
{ {
/*
Lit = lit_neg( Lit );
RetValue = sat_solver_addclause( pSat, &Lit, &Lit + 1 );
assert( RetValue );
if ( pSat->qtail != pSat->qhead )
{
RetValue = sat_solver_simplify(pSat);
assert( RetValue );
}
*/
} }
else if ( status == l_True ) else if ( status == l_True )
{ {
......
/**CFile****************************************************************
FileName [saigLoc.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Sequential AIG package.]
Synopsis [K-step induction for one property only.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: saigLoc.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "saig.h"
#include "cnf.h"
#include "satSolver.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs localization by unrolling timeframes backward.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Saig_ManInduction( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose )
{
sat_solver * pSat;
Aig_Man_t * pAigPart;
Cnf_Dat_t * pCnfPart;
Vec_Int_t * vTopVarNums;
Vec_Ptr_t * vTop, * vBot;
Aig_Obj_t * pObjPi, * pObjPiCopy, * pObjPo;
int i, f, clk, Lits[2], status, RetValue, nSatVarNum, nConfPrev;
assert( Saig_ManPoNum(p) == 1 );
Aig_ManSetPioNumbers( p );
// start the top by including the PO
vBot = Vec_PtrAlloc( 100 );
vTop = Vec_PtrAlloc( 100 );
Vec_PtrPush( vTop, Aig_ManPo(p, 0) );
// start the array of CNF variables
vTopVarNums = Vec_IntAlloc( 100 );
// start the solver
pSat = sat_solver_new();
sat_solver_setnvars( pSat, 1000 );
// iterate backward unrolling
RetValue = -1;
nSatVarNum = 0;
if ( fVerbose )
printf( "Localization parameters: FramesMax = %5d. ConflictMax = %6d.\n", nFramesMax, nConfMax );
for ( f = 0; ; f++ )
{
if ( f > 0 )
{
Aig_ManStop( pAigPart );
Cnf_DataFree( pCnfPart );
}
clk = clock();
// get the bottom
Aig_SupportNodes( p, (Aig_Obj_t **)Vec_PtrArray(vTop), Vec_PtrSize(vTop), vBot );
// derive AIG for the part between top and bottom
pAigPart = Aig_ManDupSimpleDfsPart( p, vBot, vTop );
// convert it into CNF
pCnfPart = Cnf_Derive( pAigPart, Aig_ManPoNum(pAigPart) );
Cnf_DataLift( pCnfPart, nSatVarNum );
nSatVarNum += pCnfPart->nVars;
// stitch variables of top and bot
assert( Aig_ManPoNum(pAigPart)-1 == Vec_IntSize(vTopVarNums) );
Aig_ManForEachPo( pAigPart, pObjPo, i )
{
if ( i == 0 )
{
// do not perform inductive strengthening
// if ( f > 0 )
// continue;
// add topmost literal
Lits[0] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], f>0 );
if ( !sat_solver_addclause( pSat, Lits, Lits+1 ) )
assert( 0 );
continue;
}
Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 0 );
Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 1 );
if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) )
assert( 0 );
Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i-1), 1 );
Lits[1] = toLitCond( pCnfPart->pVarNums[pObjPo->Id], 0 );
if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) )
assert( 0 );
}
// add CNF to the SAT solver
for ( i = 0; i < pCnfPart->nClauses; i++ )
if ( !sat_solver_addclause( pSat, pCnfPart->pClauses[i], pCnfPart->pClauses[i+1] ) )
break;
if ( i < pCnfPart->nClauses )
{
// printf( "SAT solver became UNSAT after adding clauses.\n" );
RetValue = 1;
break;
}
// run the SAT solver
nConfPrev = pSat->stats.conflicts;
status = sat_solver_solve( pSat, NULL, NULL, (sint64)nConfMax, 0, 0, 0 );
if ( fVerbose )
{
printf( "%3d : PI = %5d. PO = %5d. AIG = %5d. Var = %6d. Conf = %6d. ",
f+1, Aig_ManPiNum(pAigPart), Aig_ManPoNum(pAigPart), Aig_ManNodeNum(pAigPart),
nSatVarNum, pSat->stats.conflicts-nConfPrev );
PRT( "Time", clock() - clk );
}
if ( status == l_Undef )
break;
if ( status == l_False )
{
RetValue = 1;
break;
}
assert( status == l_True );
if ( f == nFramesMax - 1 )
break;
// the problem is SAT - add more clauses
// create new set of POs to derive new top
Vec_PtrClear( vTop );
Vec_PtrPush( vTop, Aig_ManPo(p, 0) );
Vec_IntClear( vTopVarNums );
Vec_PtrForEachEntry( vBot, pObjPi, i )
{
assert( Aig_ObjIsPi(pObjPi) );
if ( Saig_ObjIsLo(p, pObjPi) )
{
pObjPiCopy = pObjPi->pData;
assert( pObjPiCopy != NULL );
Vec_PtrPush( vTop, Saig_ObjLoToLi(p, pObjPi) );
Vec_IntPush( vTopVarNums, pCnfPart->pVarNums[pObjPiCopy->Id] );
}
}
}
// printf( "Completed %d interations.\n", f+1 );
// cleanup
sat_solver_delete( pSat );
Aig_ManStop( pAigPart );
Cnf_DataFree( pCnfPart );
Vec_IntFree( vTopVarNums );
Vec_PtrFree( vTop );
Vec_PtrFree( vBot );
return RetValue;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
PackageName [Sequential AIG package.] PackageName [Sequential AIG package.]
Synopsis [Localization package.] Synopsis [Localization.]
Author [Alan Mishchenko] Author [Alan Mishchenko]
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
***********************************************************************/ ***********************************************************************/
#include "saig.h" #include "saig.h"
#include "cnf.h"
#include "satSolver.h"
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// DECLARATIONS /// /// DECLARATIONS ///
...@@ -32,7 +30,7 @@ ...@@ -32,7 +30,7 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [Performs localization by unrolling timeframes backward.] Synopsis []
Description [] Description []
...@@ -41,126 +39,7 @@ ...@@ -41,126 +39,7 @@
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Saig_ManLocalization( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose )
{
sat_solver * pSat;
Vec_Int_t * vTopVarNums;
Vec_Ptr_t * vTop, * vBot;
Cnf_Dat_t * pCnfTop, * pCnfBot;
Aig_Man_t * pPartTop, * pPartBot;
Aig_Obj_t * pObj, * pObjBot;
int i, f, clk, Lits[2], status, RetValue, nSatVarNum, nConfPrev;
assert( Saig_ManPoNum(p) == 1 );
Aig_ManSetPioNumbers( p );
// start the top by including the PO
vBot = Vec_PtrAlloc( 100 );
vTop = Vec_PtrAlloc( 100 );
Vec_PtrPush( vTop, Aig_ManPo(p, 0) );
// create the manager composed of one PI/PO pair
pPartTop = Aig_ManStart( 10 );
Aig_ObjCreatePo( pPartTop, Aig_ObjCreatePi(pPartTop) );
pCnfTop = Cnf_Derive( pPartTop, 0 );
// start the array of CNF variables
vTopVarNums = Vec_IntAlloc( 100 );
Vec_IntPush( vTopVarNums, pCnfTop->pVarNums[Aig_ManPi(pPartTop,0)->Id] );
// start the solver
pSat = Cnf_DataWriteIntoSolver( pCnfTop, 1, 0 );
// iterate backward unrolling
RetValue = -1;
nSatVarNum = pCnfTop->nVars;
if ( fVerbose )
printf( "Localization parameters: FramesMax = %5d. ConflictMax = %6d.\n", nFramesMax, nConfMax );
for ( f = 0; ; f++ )
{
clk = clock();
// get the bottom
Aig_SupportNodes( p, (Aig_Obj_t **)Vec_PtrArray(vTop), Vec_PtrSize(vTop), vBot );
// derive AIG for the part between top and bottom
pPartBot = Aig_ManDupSimpleDfsPart( p, vBot, vTop );
// convert it into CNF
pCnfBot = Cnf_Derive( pPartBot, Aig_ManPoNum(pPartBot) );
Cnf_DataLift( pCnfBot, nSatVarNum );
nSatVarNum += pCnfBot->nVars;
// stitch variables of top and bot
assert( Aig_ManPoNum(pPartBot) == Vec_IntSize(vTopVarNums) );
Aig_ManForEachPo( pPartBot, pObjBot, i )
{
Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i), 0 );
Lits[1] = toLitCond( pCnfBot->pVarNums[pObjBot->Id], 1 );
if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) )
assert( 0 );
Lits[0] = toLitCond( Vec_IntEntry(vTopVarNums, i), 1 );
Lits[1] = toLitCond( pCnfBot->pVarNums[pObjBot->Id], 0 );
if ( !sat_solver_addclause( pSat, Lits, Lits+2 ) )
assert( 0 );
}
// add CNF to the SAT solver
for ( i = 0; i < pCnfBot->nClauses; i++ )
if ( !sat_solver_addclause( pSat, pCnfBot->pClauses[i], pCnfBot->pClauses[i+1] ) )
break;
if ( i < pCnfBot->nClauses )
{
// printf( "SAT solver became UNSAT after adding clauses.\n" );
RetValue = 1;
break;
}
// run the SAT solver
nConfPrev = pSat->stats.conflicts;
status = sat_solver_solve( pSat, NULL, NULL, (sint64)nConfMax, 0, 0, 0 );
if ( fVerbose )
{
printf( "%3d : PI = %5d. PO = %5d. AIG = %5d. Var = %6d. Conf = %6d. ",
f+1, Aig_ManPiNum(pPartBot), Aig_ManPoNum(pPartBot), Aig_ManNodeNum(pPartBot),
nSatVarNum, pSat->stats.conflicts-nConfPrev );
PRT( "Time", clock() - clk );
}
if ( status == l_Undef )
break;
if ( status == l_False )
{
RetValue = 1;
break;
}
assert( status == l_True );
if ( f == nFramesMax - 1 )
break;
// the problem is SAT - add more clauses
// create new set of POs to derive new top
Vec_PtrClear( vTop );
Vec_IntClear( vTopVarNums );
Vec_PtrForEachEntry( vBot, pObj, i )
{
assert( Aig_ObjIsPi(pObj) );
if ( Saig_ObjIsLo(p, pObj) )
{
pObjBot = pObj->pData;
assert( pObjBot != NULL );
Vec_PtrPush( vTop, Saig_ObjLoToLi(p, pObj) );
Vec_IntPush( vTopVarNums, pCnfBot->pVarNums[pObjBot->Id] );
}
}
// remove old top and replace it by bottom
Aig_ManStop( pPartTop );
pPartTop = pPartBot;
pPartBot = NULL;
Cnf_DataFree( pCnfTop );
pCnfTop = pCnfBot;
pCnfBot = NULL;
}
// printf( "Completed %d interations.\n", f+1 );
// cleanup
sat_solver_delete( pSat );
Aig_ManStop( pPartTop );
Cnf_DataFree( pCnfTop );
Aig_ManStop( pPartBot );
Cnf_DataFree( pCnfBot );
Vec_IntFree( vTopVarNums );
Vec_PtrFree( vTop );
Vec_PtrFree( vBot );
return RetValue;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
......
...@@ -8,6 +8,7 @@ SRC += src/aig/ssw/sswAig.c \ ...@@ -8,6 +8,7 @@ SRC += src/aig/ssw/sswAig.c \
src/aig/ssw/sswPart.c \ src/aig/ssw/sswPart.c \
src/aig/ssw/sswPairs.c \ src/aig/ssw/sswPairs.c \
src/aig/ssw/sswSat.c \ src/aig/ssw/sswSat.c \
src/aig/ssw/sswSemi.c \
src/aig/ssw/sswSim.c \ src/aig/ssw/sswSim.c \
src/aig/ssw/sswSimSat.c \ src/aig/ssw/sswSimSat.c \
src/aig/ssw/sswSweep.c \ src/aig/ssw/sswSweep.c \
......
...@@ -50,8 +50,8 @@ struct Ssw_Pars_t_ ...@@ -50,8 +50,8 @@ struct Ssw_Pars_t_
int nBTLimit; // conflict limit at a node int nBTLimit; // conflict limit at a node
int nBTLimitGlobal;// conflict limit for multiple runs int nBTLimitGlobal;// conflict limit for multiple runs
int nMinDomSize; // min clock domain considered for optimization int nMinDomSize; // min clock domain considered for optimization
int nItersStop; // stop after the given number of iterations
int fPolarFlip; // uses polarity adjustment int fPolarFlip; // uses polarity adjustment
int fSkipCheck; // do not run equivalence check for unaffected cones
int fLatchCorr; // perform register correspondence int fLatchCorr; // perform register correspondence
int fSemiFormal; // enable semiformal filtering int fSemiFormal; // enable semiformal filtering
int fUniqueness; // enable uniqueness constraints int fUniqueness; // enable uniqueness constraints
...@@ -88,13 +88,13 @@ struct Ssw_Cex_t_ ...@@ -88,13 +88,13 @@ struct Ssw_Cex_t_
/*=== sswAbs.c ==========================================================*/ /*=== sswAbs.c ==========================================================*/
extern Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax, int fVerbose ); extern Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax, int fVerbose );
/*=== sswBmc.c ==========================================================*/
extern int Ssw_BmcDynamic( Aig_Man_t * pAig, int nFramesMax, int nConfLimit, int fVerbose, int * piFrame );
/*=== sswCore.c ==========================================================*/ /*=== sswCore.c ==========================================================*/
extern void Ssw_ManSetDefaultParams( Ssw_Pars_t * p ); extern void Ssw_ManSetDefaultParams( Ssw_Pars_t * p );
extern void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p ); extern void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p );
extern Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ); extern Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
extern Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ); extern Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
/*=== sswLoc.c ==========================================================*/
extern int Saig_ManLocalization( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose );
/*=== sswMiter.c ===================================================*/ /*=== sswMiter.c ===================================================*/
extern int Ssw_SecSpecialMiter( Aig_Man_t * pMiter, int fVerbose ); extern int Ssw_SecSpecialMiter( Aig_Man_t * pMiter, int fVerbose );
/*=== sswPart.c ==========================================================*/ /*=== sswPart.c ==========================================================*/
......
...@@ -30,6 +30,50 @@ ...@@ -30,6 +30,50 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [Starts the SAT manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Frm_t * Ssw_FrmStart( Aig_Man_t * pAig )
{
Ssw_Frm_t * p;
p = ALLOC( Ssw_Frm_t, 1 );
memset( p, 0, sizeof(Ssw_Frm_t) );
p->pAig = pAig;
p->nObjs = Aig_ManObjNumMax( pAig );
p->nFrames = 0;
p->pFrames = NULL;
p->vAig2Frm = Vec_PtrAlloc( 0 );
Vec_PtrFill( p->vAig2Frm, 2 * p->nObjs, NULL );
return p;
}
/**Function*************************************************************
Synopsis [Starts the SAT manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_FrmStop( Ssw_Frm_t * p )
{
if ( p->pFrames )
Aig_ManStop( p->pFrames );
Vec_PtrFree( p->vAig2Frm );
free( p );
}
/**Function*************************************************************
Synopsis [Performs speculative reduction for one node.] Synopsis [Performs speculative reduction for one node.]
Description [] Description []
...@@ -164,7 +208,7 @@ Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p ) ...@@ -164,7 +208,7 @@ Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p )
assert( Aig_ManRegNum(p->pAig) > 0 ); assert( Aig_ManRegNum(p->pAig) > 0 );
assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) ); assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
p->nConstrTotal = p->nConstrReduced = 0; p->nConstrTotal = p->nConstrReduced = 0;
// start the fraig package // start the fraig package
pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames ); pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames );
// map constants and PIs // map constants and PIs
...@@ -190,8 +234,8 @@ Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p ) ...@@ -190,8 +234,8 @@ Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p )
// remove dangling nodes // remove dangling nodes
Aig_ManCleanup( pFrames ); Aig_ManCleanup( pFrames );
Aig_ManSetRegNum( pFrames, Aig_ManRegNum(p->pAig) ); Aig_ManSetRegNum( pFrames, Aig_ManRegNum(p->pAig) );
printf( "SpecRed: Total constraints = %d. Reduced constraints = %d.\n", // printf( "SpecRed: Total constraints = %d. Reduced constraints = %d.\n",
p->nConstrTotal, p->nConstrReduced ); // p->nConstrTotal, p->nConstrReduced );
return pFrames; return pFrames;
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
PackageName [Inductive prover with constraints.] PackageName [Inductive prover with constraints.]
Synopsis [Bounded model checker for equivalence clases.] Synopsis [Bounded model checker using dynamic unrolling.]
Author [Alan Mishchenko] Author [Alan Mishchenko]
...@@ -24,32 +24,13 @@ ...@@ -24,32 +24,13 @@
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
typedef struct Ssw_Bmc_t_ Ssw_Bmc_t; // BMC manager
struct Ssw_Bmc_t_
{
// parameters
int nConfMaxStart; // the starting conflict limit
int nConfMax; // the intermediate conflict limit
int nFramesSweep; // the number of frames to sweep
int fVerbose; // prints output statistics
// equivalences considered
Ssw_Man_t * pMan; // SAT sweeping manager
Vec_Ptr_t * vTargets; // the nodes that are watched
// storage for patterns
int nPatternsAlloc; // the max number of interesting states
int nPatterns; // the number of patterns
Vec_Ptr_t * vPatterns; // storage for the interesting states
Vec_Int_t * vHistory; // what state and how many steps
};
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS /// /// FUNCTION DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/**Function************************************************************* /**Function*************************************************************
Synopsis [] Synopsis [Incrementally unroll the timeframes.]
Description [] Description []
...@@ -58,60 +39,43 @@ struct Ssw_Bmc_t_ ...@@ -58,60 +39,43 @@ struct Ssw_Bmc_t_
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Ssw_Bmc_t * Ssw_BmcManStart( Ssw_Man_t * pMan, int nConfMax, int fVerbose ) Aig_Obj_t * Ssw_BmcUnroll_rec( Ssw_Frm_t * pFrm, Aig_Obj_t * pObj, int f )
{ {
Ssw_Bmc_t * p; Aig_Obj_t * pRes, * pRes0, * pRes1;
Aig_Obj_t * pObj; if ( (pRes = Ssw_ObjFrame_(pFrm, pObj, f)) )
int i; return pRes;
// create interpolation manager if ( Aig_ObjIsConst1(pObj) )
p = ALLOC( Ssw_Bmc_t, 1 ); pRes = Aig_ManConst1( pFrm->pFrames );
memset( p, 0, sizeof(Ssw_Bmc_t) ); else if ( Saig_ObjIsPi(pFrm->pAig, pObj) )
p->nConfMaxStart = nConfMax; pRes = Aig_ObjCreatePi( pFrm->pFrames );
p->nConfMax = nConfMax; else if ( Aig_ObjIsPo(pObj) )
p->nFramesSweep = AIG_MAX( (1<<21)/Aig_ManNodeNum(pMan->pAig), pMan->nFrames ); {
p->fVerbose = fVerbose; Ssw_BmcUnroll_rec( pFrm, Aig_ObjFanin0(pObj), f );
// equivalences considered pRes = Ssw_ObjChild0Fra_( pFrm, pObj, f );
p->pMan = pMan; }
p->vTargets = Vec_PtrAlloc( Saig_ManPoNum(p->pMan->pAig) ); else if ( Saig_ObjIsLo(pFrm->pAig, pObj) )
Saig_ManForEachPo( p->pMan->pAig, pObj, i ) {
Vec_PtrPush( p->vTargets, Aig_ObjFanin0(pObj) ); if ( f == 0 )
// storage for patterns pRes = Aig_ManConst0( pFrm->pFrames );
p->nPatternsAlloc = 512; else
p->nPatterns = 1; pRes = Ssw_BmcUnroll_rec( pFrm, Saig_ObjLoToLi(pFrm->pAig, pObj), f-1 );
p->vPatterns = Vec_PtrAllocSimInfo( Aig_ManRegNum(p->pMan->pAig), Aig_BitWordNum(p->nPatternsAlloc) ); }
Vec_PtrCleanSimInfo( p->vPatterns, 0, Aig_BitWordNum(p->nPatternsAlloc) ); else
p->vHistory = Vec_IntAlloc( 100 ); {
Vec_IntPush( p->vHistory, 0 ); assert( Aig_ObjIsNode(pObj) );
// update arrays of the manager Ssw_BmcUnroll_rec( pFrm, Aig_ObjFanin0(pObj), f );
free( p->pMan->pNodeToFrames ); Ssw_BmcUnroll_rec( pFrm, Aig_ObjFanin1(pObj), f );
Vec_IntFree( p->pMan->vSatVars ); pRes0 = Ssw_ObjChild0Fra_( pFrm, pObj, f );
p->pMan->pNodeToFrames = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pMan->pAig) * p->nFramesSweep ); pRes1 = Ssw_ObjChild1Fra_( pFrm, pObj, f );
p->pMan->vSatVars = Vec_IntStart( Aig_ManObjNumMax(p->pMan->pAig) * (p->nFramesSweep+1) ); pRes = Aig_And( pFrm->pFrames, pRes0, pRes1 );
return p; }
} Ssw_ObjSetFrame_( pFrm, pObj, f, pRes );
return pRes;
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_BmcManStop( Ssw_Bmc_t * p )
{
Vec_PtrFree( p->vTargets );
Vec_PtrFree( p->vPatterns );
Vec_IntFree( p->vHistory );
free( p );
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [] Synopsis [Derives counter-example.]
Description [] Description []
...@@ -120,46 +84,34 @@ void Ssw_BmcManStop( Ssw_Bmc_t * p ) ...@@ -120,46 +84,34 @@ void Ssw_BmcManStop( Ssw_Bmc_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ssw_BmcCheckTargets( Ssw_Bmc_t * p ) Ssw_Cex_t * Ssw_BmcGetCounterExample( Ssw_Frm_t * pFrm, Ssw_Sat_t * pSat, int iPo, int iFrame )
{ {
Aig_Obj_t * pObj; Ssw_Cex_t * pCex;
int i; Aig_Obj_t * pObj, * pObjFrames;
Vec_PtrForEachEntry( p->vTargets, pObj, i ) int f, i, nShift;
if ( !Ssw_ObjIsConst1Cand(p->pMan->pAig, pObj) ) assert( Saig_ManRegNum(pFrm->pAig) > 0 );
return 1; // allocate the counter example
return 0; pCex = Ssw_SmlAllocCounterExample( Saig_ManRegNum(pFrm->pAig), Saig_ManPiNum(pFrm->pAig), iFrame + 1 );
pCex->iPo = iPo;
pCex->iFrame = iFrame;
// create data-bits
nShift = Saig_ManRegNum(pFrm->pAig);
for ( f = 0; f <= iFrame; f++, nShift += Saig_ManPiNum(pFrm->pAig) )
Saig_ManForEachPi( pFrm->pAig, pObj, i )
{
pObjFrames = Ssw_ObjFrame_(pFrm, pObj, f);
if ( pObjFrames == NULL )
continue;
if ( Ssw_CnfGetNodeValue( pSat, pObjFrames ) )
Aig_InfoSetBit( pCex->pData, nShift + i );
}
return pCex;
} }
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManFilterBmcSavePattern( Ssw_Bmc_t * p )
{
unsigned * pInfo;
Aig_Obj_t * pObj;
int i;
if ( p->nPatterns >= p->nPatternsAlloc )
return;
Saig_ManForEachLo( p->pMan->pAig, pObj, i )
{
pInfo = Vec_PtrEntry( p->vPatterns, i );
if ( Aig_InfoHasBit( p->pMan->pPatWords, Saig_ManPiNum(p->pMan->pAig) + i ) )
Aig_InfoSetBit( pInfo, p->nPatterns );
}
p->nPatterns++;
}
/**Function************************************************************* /**Function*************************************************************
Synopsis [Performs fraiging for the internal nodes.] Synopsis [Performs BMC for the given AIG.]
Description [] Description []
...@@ -168,143 +120,95 @@ void Ssw_ManFilterBmcSavePattern( Ssw_Bmc_t * p ) ...@@ -168,143 +120,95 @@ void Ssw_ManFilterBmcSavePattern( Ssw_Bmc_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ssw_ManFilterBmc( Ssw_Bmc_t * pBmc, int iPat, int fCheckTargets ) int Ssw_BmcDynamic( Aig_Man_t * pAig, int nFramesMax, int nConfLimit, int fVerbose, int * piFrame )
{ {
Ssw_Man_t * p = pBmc->pMan; Ssw_Frm_t * pFrm;
Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo; Ssw_Sat_t * pSat;
unsigned * pInfo; Aig_Obj_t * pObj, * pObjFrame;
int i, f, clk, RetValue, fFirst = 0; int status, clkPart, Lit, i, f, RetValue;
clk = clock();
// start managers
// start initialized timeframes assert( Saig_ManRegNum(pAig) > 0 );
p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * 3 ); Aig_ManSetPioNumbers( pAig );
Saig_ManForEachLo( p->pAig, pObj, i ) pSat = Ssw_SatStart( 0 );
pFrm = Ssw_FrmStart( pAig );
pFrm->pFrames = Aig_ManStart( Aig_ManObjNumMax(pAig) * 3 );
// report statistics
if ( fVerbose )
{ {
pInfo = Vec_PtrEntry( pBmc->vPatterns, i ); printf( "AIG: PI/PO/Reg = %d/%d/%d. Node = %6d. Lev = %5d.\n",
pObjNew = Aig_NotCond( Aig_ManConst1(p->pFrames), !Aig_InfoHasBit(pInfo, iPat) ); Saig_ManPiNum(pAig), Saig_ManPoNum(pAig), Saig_ManRegNum(pAig),
Ssw_ObjSetFrame( p, pObj, 0, pObjNew ); Aig_ManNodeNum(pAig), Aig_ManLevelNum(pAig) );
fflush( stdout );
} }
// perform dynamic unrolling
// sweep internal nodes RetValue = -1;
Ssw_ManStartSolver( p ); for ( f = 0; f < nFramesMax; f++ )
RetValue = pBmc->nFramesSweep;
for ( f = 0; f < pBmc->nFramesSweep; f++ )
{ {
// map constants and PIs clkPart = clock();
Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) ); Saig_ManForEachPo( pAig, pObj, i )
Saig_ManForEachPi( p->pAig, pObj, i )
Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) );
// sweep internal nodes
Aig_ManForEachNode( p->pAig, pObj, i )
{ {
pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) ); // unroll the circuit for this output
Ssw_ObjSetFrame( p, pObj, f, pObjNew ); Ssw_BmcUnroll_rec( pFrm, pObj, f );
if ( Ssw_ManSweepNode( p, pObj, f, 1 ) ) pObjFrame = Ssw_ObjFrame_( pFrm, pObj, f );
Ssw_CnfNodeAddToSolver( pSat, Aig_Regular(pObjFrame) );
status = sat_solver_simplify(pSat->pSat);
assert( status );
// solve
Lit = toLitCond( Ssw_ObjSatNum(pSat,pObjFrame), Aig_IsComplement(pObjFrame) );
if ( fVerbose )
{
printf( "Solving output %2d of frame %3d ... \r",
i % Saig_ManPoNum(pAig), i / Saig_ManPoNum(pAig) );
}
status = sat_solver_solve( pSat->pSat, &Lit, &Lit + 1, (sint64)nConfLimit, (sint64)0, (sint64)0, (sint64)0 );
if ( status == l_False )
{ {
Ssw_ManFilterBmcSavePattern( pBmc ); /*
if ( fFirst == 0 ) Lit = lit_neg( Lit );
RetValue = sat_solver_addclause( pSat->pSat, &Lit, &Lit + 1 );
assert( RetValue );
if ( pSat->pSat->qtail != pSat->pSat->qhead )
{ {
fFirst = 1; RetValue = sat_solver_simplify(pSat->pSat);
pBmc->nConfMax *= 10; assert( RetValue );
} }
*/
RetValue = 1;
continue;
} }
if ( f > 0 && p->pSat->stats.conflicts >= pBmc->nConfMax ) else if ( status == l_True )
{ {
pAig->pSeqModel = Ssw_BmcGetCounterExample( pFrm, pSat, i, f );
if ( piFrame )
*piFrame = f;
RetValue = 0;
break;
}
else
{
if ( piFrame )
*piFrame = f;
RetValue = -1; RetValue = -1;
break; break;
} }
} }
// quit if this is the last timeframe
if ( p->pSat->stats.conflicts >= pBmc->nConfMax )
{
RetValue += f + 1;
break;
}
if ( fCheckTargets && Ssw_BmcCheckTargets( pBmc ) )
break;
// transfer latch input to the latch outputs
// build logic cones for register outputs
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
{
pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f);
Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) );
}
//printf( "Frame %2d : Conflicts = %6d. \n", f, p->pSat->stats.conflicts );
}
if ( fFirst )
pBmc->nConfMax /= 10;
// cleanup
Ssw_ClassesCheck( p->ppClasses );
p->timeBmc += clock() - clk;
return RetValue;
}
/**Function*************************************************************
Synopsis [Returns 1 if one of the targets has failed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_FilterUsingBmc( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose )
{
Ssw_Bmc_t * p;
int RetValue, Frames, Iter, clk = clock();
p = Ssw_BmcManStart( pMan, nConfMax, fVerbose );
if ( fCheckTargets && Ssw_BmcCheckTargets( p ) )
{
assert( 0 );
Ssw_BmcManStop( p );
return 1;
}
if ( fVerbose )
{
printf( "AIG : Const = %6d. Cl = %6d. Nodes = %6d. ConfMax = %6d. FramesMax = %6d.\n",
Ssw_ClassesCand1Num(p->pMan->ppClasses), Ssw_ClassesClassNum(p->pMan->ppClasses),
Aig_ManNodeNum(p->pMan->pAig), p->nConfMax, p->nFramesSweep );
}
RetValue = 0;
for ( Iter = 0; Iter < p->nPatterns; Iter++ )
{
clk = clock();
Frames = Ssw_ManFilterBmc( p, Iter, fCheckTargets );
if ( fVerbose ) if ( fVerbose )
{ {
printf( "%3d : Const = %6d. Cl = %6d. NR = %6d. F = %3d. C = %5d. P = %3d. %s ", printf( "Solved %2d outputs of frame %3d. ", Saig_ManPoNum(pAig), f );
Iter, Ssw_ClassesCand1Num(p->pMan->ppClasses), Ssw_ClassesClassNum(p->pMan->ppClasses), printf( "Conf =%8.0f. Var =%8d. AIG=%9d. ",
Aig_ManNodeNum(p->pMan->pFrames), Frames, (int)p->pMan->pSat->stats.conflicts, p->nPatterns, (double)pSat->pSat->stats.conflicts,
p->pMan->nSatFailsReal? "f" : " " ); pSat->nSatVars, Aig_ManNodeNum(pFrm->pFrames) );
PRT( "T", clock() - clk ); PRT( "T", clock() - clkPart );
} clkPart = clock();
Ssw_ManCleanup( p->pMan ); fflush( stdout );
if ( fCheckTargets && Ssw_BmcCheckTargets( p ) )
{
printf( "Target is hit!!!\n" );
RetValue = 1;
} }
if ( p->nPatterns >= p->nPatternsAlloc ) if ( RetValue != 1 )
break; break;
} }
Ssw_BmcManStop( p );
Ssw_SatStop( pSat );
pMan->nStrangers = 0; Ssw_FrmStop( pFrm );
pMan->nSatCalls = 0;
pMan->nSatProof = 0;
pMan->nSatFailsReal = 0;
pMan->nSatFailsTotal = 0;
pMan->nSatCallsUnsat = 0;
pMan->nSatCallsSat = 0;
pMan->timeSimSat = 0;
pMan->timeSat = 0;
pMan->timeSatSat = 0;
pMan->timeSatUnsat = 0;
pMan->timeSatUndec = 0;
return RetValue; return RetValue;
} }
......
...@@ -30,6 +30,63 @@ ...@@ -30,6 +30,63 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [Starts the SAT manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Sat_t * Ssw_SatStart( int fPolarFlip )
{
Ssw_Sat_t * p;
int Lit;
p = ALLOC( Ssw_Sat_t, 1 );
memset( p, 0, sizeof(Ssw_Sat_t) );
p->pAig = NULL;
p->fPolarFlip = fPolarFlip;
p->vSatVars = Vec_IntStart( 10000 );
p->vFanins = Vec_PtrAlloc( 100 );
p->vUsedPis = Vec_PtrAlloc( 100 );
p->pSat = sat_solver_new();
sat_solver_setnvars( p->pSat, 1000 );
// var 0 is not used
// var 1 is reserved for const1 node - add the clause
p->nSatVars = 1;
Lit = toLit( p->nSatVars );
if ( fPolarFlip )
Lit = lit_neg( Lit );
sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
// Ssw_ObjSetSatNum( p, Aig_ManConst1(p->pAig), p->nSatVars++ );
Vec_IntWriteEntry( p->vSatVars, 0, p->nSatVars++ );
return p;
}
/**Function*************************************************************
Synopsis [Stop the SAT manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SatStop( Ssw_Sat_t * p )
{
if ( p->pSat )
sat_solver_delete( p->pSat );
Vec_IntFree( p->vSatVars );
Vec_PtrFree( p->vFanins );
Vec_PtrFree( p->vUsedPis );
free( p );
}
/**Function*************************************************************
Synopsis [Addes clauses to the solver.] Synopsis [Addes clauses to the solver.]
Description [] Description []
...@@ -39,7 +96,7 @@ ...@@ -39,7 +96,7 @@
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode ) void Ssw_AddClausesMux( Ssw_Sat_t * p, Aig_Obj_t * pNode )
{ {
Aig_Obj_t * pNodeI, * pNodeT, * pNodeE; Aig_Obj_t * pNodeI, * pNodeT, * pNodeE;
int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE; int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
...@@ -68,7 +125,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode ) ...@@ -68,7 +125,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode )
pLits[0] = toLitCond(VarI, 1); pLits[0] = toLitCond(VarI, 1);
pLits[1] = toLitCond(VarT, 1^fCompT); pLits[1] = toLitCond(VarT, 1^fCompT);
pLits[2] = toLitCond(VarF, 0); pLits[2] = toLitCond(VarF, 0);
if ( p->pPars->fPolarFlip ) if ( p->fPolarFlip )
{ {
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( Aig_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
...@@ -79,7 +136,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode ) ...@@ -79,7 +136,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode )
pLits[0] = toLitCond(VarI, 1); pLits[0] = toLitCond(VarI, 1);
pLits[1] = toLitCond(VarT, 0^fCompT); pLits[1] = toLitCond(VarT, 0^fCompT);
pLits[2] = toLitCond(VarF, 1); pLits[2] = toLitCond(VarF, 1);
if ( p->pPars->fPolarFlip ) if ( p->fPolarFlip )
{ {
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( Aig_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
...@@ -90,7 +147,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode ) ...@@ -90,7 +147,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode )
pLits[0] = toLitCond(VarI, 0); pLits[0] = toLitCond(VarI, 0);
pLits[1] = toLitCond(VarE, 1^fCompE); pLits[1] = toLitCond(VarE, 1^fCompE);
pLits[2] = toLitCond(VarF, 0); pLits[2] = toLitCond(VarF, 0);
if ( p->pPars->fPolarFlip ) if ( p->fPolarFlip )
{ {
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
...@@ -101,7 +158,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode ) ...@@ -101,7 +158,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode )
pLits[0] = toLitCond(VarI, 0); pLits[0] = toLitCond(VarI, 0);
pLits[1] = toLitCond(VarE, 0^fCompE); pLits[1] = toLitCond(VarE, 0^fCompE);
pLits[2] = toLitCond(VarF, 1); pLits[2] = toLitCond(VarF, 1);
if ( p->pPars->fPolarFlip ) if ( p->fPolarFlip )
{ {
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
...@@ -126,7 +183,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode ) ...@@ -126,7 +183,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode )
pLits[0] = toLitCond(VarT, 0^fCompT); pLits[0] = toLitCond(VarT, 0^fCompT);
pLits[1] = toLitCond(VarE, 0^fCompE); pLits[1] = toLitCond(VarE, 0^fCompE);
pLits[2] = toLitCond(VarF, 1); pLits[2] = toLitCond(VarF, 1);
if ( p->pPars->fPolarFlip ) if ( p->fPolarFlip )
{ {
if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
...@@ -137,7 +194,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode ) ...@@ -137,7 +194,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode )
pLits[0] = toLitCond(VarT, 1^fCompT); pLits[0] = toLitCond(VarT, 1^fCompT);
pLits[1] = toLitCond(VarE, 1^fCompE); pLits[1] = toLitCond(VarE, 1^fCompE);
pLits[2] = toLitCond(VarF, 0); pLits[2] = toLitCond(VarF, 0);
if ( p->pPars->fPolarFlip ) if ( p->fPolarFlip )
{ {
if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
...@@ -158,7 +215,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode ) ...@@ -158,7 +215,7 @@ void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Ssw_AddClausesSuper( Ssw_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper ) void Ssw_AddClausesSuper( Ssw_Sat_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper )
{ {
Aig_Obj_t * pFanin; Aig_Obj_t * pFanin;
int * pLits, nLits, RetValue, i; int * pLits, nLits, RetValue, i;
...@@ -173,7 +230,7 @@ void Ssw_AddClausesSuper( Ssw_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper ) ...@@ -173,7 +230,7 @@ void Ssw_AddClausesSuper( Ssw_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper )
{ {
pLits[0] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), Aig_IsComplement(pFanin)); pLits[0] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), Aig_IsComplement(pFanin));
pLits[1] = toLitCond(Ssw_ObjSatNum(p,pNode), 1); pLits[1] = toLitCond(Ssw_ObjSatNum(p,pNode), 1);
if ( p->pPars->fPolarFlip ) if ( p->fPolarFlip )
{ {
if ( Aig_Regular(pFanin)->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( Aig_Regular(pFanin)->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( pNode->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( pNode->fPhase ) pLits[1] = lit_neg( pLits[1] );
...@@ -185,13 +242,13 @@ void Ssw_AddClausesSuper( Ssw_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper ) ...@@ -185,13 +242,13 @@ void Ssw_AddClausesSuper( Ssw_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper )
Vec_PtrForEachEntry( vSuper, pFanin, i ) Vec_PtrForEachEntry( vSuper, pFanin, i )
{ {
pLits[i] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), !Aig_IsComplement(pFanin)); pLits[i] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), !Aig_IsComplement(pFanin));
if ( p->pPars->fPolarFlip ) if ( p->fPolarFlip )
{ {
if ( Aig_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] ); if ( Aig_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] );
} }
} }
pLits[nLits-1] = toLitCond(Ssw_ObjSatNum(p,pNode), 0); pLits[nLits-1] = toLitCond(Ssw_ObjSatNum(p,pNode), 0);
if ( p->pPars->fPolarFlip ) if ( p->fPolarFlip )
{ {
if ( pNode->fPhase ) pLits[nLits-1] = lit_neg( pLits[nLits-1] ); if ( pNode->fPhase ) pLits[nLits-1] = lit_neg( pLits[nLits-1] );
} }
...@@ -221,6 +278,7 @@ void Ssw_CollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int ...@@ -221,6 +278,7 @@ void Ssw_CollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int
Vec_PtrPushUnique( vSuper, pObj ); Vec_PtrPushUnique( vSuper, pObj );
return; return;
} }
// pObj->fMarkA = 1;
// go through the branches // go through the branches
Ssw_CollectSuper_rec( Aig_ObjChild0(pObj), vSuper, 0, fUseMuxes ); Ssw_CollectSuper_rec( Aig_ObjChild0(pObj), vSuper, 0, fUseMuxes );
Ssw_CollectSuper_rec( Aig_ObjChild1(pObj), vSuper, 0, fUseMuxes ); Ssw_CollectSuper_rec( Aig_ObjChild1(pObj), vSuper, 0, fUseMuxes );
...@@ -256,7 +314,7 @@ void Ssw_CollectSuper( Aig_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper ) ...@@ -256,7 +314,7 @@ void Ssw_CollectSuper( Aig_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Ssw_ObjAddToFrontier( Ssw_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontier ) void Ssw_ObjAddToFrontier( Ssw_Sat_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontier )
{ {
assert( !Aig_IsComplement(pObj) ); assert( !Aig_IsComplement(pObj) );
if ( Ssw_ObjSatNum(p,pObj) ) if ( Ssw_ObjSatNum(p,pObj) )
...@@ -264,12 +322,10 @@ void Ssw_ObjAddToFrontier( Ssw_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontie ...@@ -264,12 +322,10 @@ void Ssw_ObjAddToFrontier( Ssw_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontie
assert( Ssw_ObjSatNum(p,pObj) == 0 ); assert( Ssw_ObjSatNum(p,pObj) == 0 );
if ( Aig_ObjIsConst1(pObj) ) if ( Aig_ObjIsConst1(pObj) )
return; return;
if ( p->pPars->fLatchCorrOpt ) // pObj->fMarkA = 1;
{ // save PIs (used by register correspondence)
Vec_PtrPush( p->vUsedNodes, pObj ); if ( Aig_ObjIsPi(pObj) )
if ( Aig_ObjIsPi(pObj) ) Vec_PtrPush( p->vUsedPis, pObj );
Vec_PtrPush( p->vUsedPis, pObj );
}
Ssw_ObjSetSatNum( p, pObj, p->nSatVars++ ); Ssw_ObjSetSatNum( p, pObj, p->nSatVars++ );
sat_solver_setnvars( p->pSat, 100 * (1 + p->nSatVars / 100) ); sat_solver_setnvars( p->pSat, 100 * (1 + p->nSatVars / 100) );
if ( Aig_ObjIsNode(pObj) ) if ( Aig_ObjIsNode(pObj) )
...@@ -287,7 +343,7 @@ void Ssw_ObjAddToFrontier( Ssw_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontie ...@@ -287,7 +343,7 @@ void Ssw_ObjAddToFrontier( Ssw_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontie
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Ssw_CnfNodeAddToSolver( Ssw_Man_t * p, Aig_Obj_t * pObj ) void Ssw_CnfNodeAddToSolver( Ssw_Sat_t * p, Aig_Obj_t * pObj )
{ {
Vec_Ptr_t * vFrontier; Vec_Ptr_t * vFrontier;
Aig_Obj_t * pNode, * pFanin; Aig_Obj_t * pNode, * pFanin;
...@@ -327,6 +383,36 @@ void Ssw_CnfNodeAddToSolver( Ssw_Man_t * p, Aig_Obj_t * pObj ) ...@@ -327,6 +383,36 @@ void Ssw_CnfNodeAddToSolver( Ssw_Man_t * p, Aig_Obj_t * pObj )
} }
/**Function*************************************************************
Synopsis [Copy pattern from the solver into the internal storage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_CnfGetNodeValue( Ssw_Sat_t * p, Aig_Obj_t * pObj )
{
int Value0, Value1, nVarNum;
assert( !Aig_IsComplement(pObj) );
nVarNum = Ssw_ObjSatNum( p, pObj );
if ( nVarNum > 0 )
return sat_solver_var_value( p->pSat, nVarNum );
// if ( pObj->fMarkA == 1 )
// return 0;
if ( Aig_ObjIsPi(pObj) )
return 0;
assert( Aig_ObjIsNode(pObj) );
Value0 = Ssw_CnfGetNodeValue( p, Aig_ObjFanin0(pObj) );
Value0 ^= Aig_ObjFaninC0(pObj);
Value1 = Ssw_CnfGetNodeValue( p, Aig_ObjFanin1(pObj) );
Value1 ^= Aig_ObjFaninC1(pObj);
return Value0 & Value1;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
......
...@@ -45,13 +45,13 @@ void Ssw_ManSetDefaultParams( Ssw_Pars_t * p ) ...@@ -45,13 +45,13 @@ void Ssw_ManSetDefaultParams( Ssw_Pars_t * p )
p->nPartSize = 0; // size of the partition p->nPartSize = 0; // size of the partition
p->nOverSize = 0; // size of the overlap between partitions p->nOverSize = 0; // size of the overlap between partitions
p->nFramesK = 1; // the induction depth p->nFramesK = 1; // the induction depth
p->nFramesAddSim = 0; // additional frames to simulate p->nFramesAddSim = 2; // additional frames to simulate
p->nConstrs = 0; // treat the last nConstrs POs as seq constraints p->nConstrs = 0; // treat the last nConstrs POs as seq constraints
p->nBTLimit = 1000; // conflict limit at a node p->nBTLimit = 1000; // conflict limit at a node
p->nBTLimitGlobal = 5000000; // conflict limit for all runs p->nBTLimitGlobal = 5000000; // conflict limit for all runs
p->nMinDomSize = 100; // min clock domain considered for optimization p->nMinDomSize = 100; // min clock domain considered for optimization
p->nItersStop = 0; // stop after the given number of iterations
p->fPolarFlip = 0; // uses polarity adjustment p->fPolarFlip = 0; // uses polarity adjustment
p->fSkipCheck = 0; // do not run equivalence check for unaffected cones
p->fLatchCorr = 0; // performs register correspondence p->fLatchCorr = 0; // performs register correspondence
p->fSemiFormal = 0; // enable semiformal filtering p->fSemiFormal = 0; // enable semiformal filtering
p->fUniqueness = 0; // enable uniqueness constraints p->fUniqueness = 0; // enable uniqueness constraints
...@@ -111,7 +111,12 @@ Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p ) ...@@ -111,7 +111,12 @@ Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p )
} }
if ( !p->pPars->fLatchCorr ) if ( !p->pPars->fLatchCorr )
{ {
p->pMSat = Ssw_SatStart( 0 );
Ssw_ManSweepBmc( p ); Ssw_ManSweepBmc( p );
if ( p->pPars->nFramesK > 1 && p->pPars->fUniqueness )
Ssw_UniqueRegisterPairInfo( p );
Ssw_SatStop( p->pMSat );
p->pMSat = NULL;
Ssw_ManCleanup( p ); Ssw_ManCleanup( p );
} }
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
...@@ -120,20 +125,23 @@ Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p ) ...@@ -120,20 +125,23 @@ Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p )
Ssw_ClassesPrint( p->ppClasses, 0 ); Ssw_ClassesPrint( p->ppClasses, 0 );
} }
// apply semi-formal filtering // apply semi-formal filtering
/*
if ( p->pPars->fSemiFormal ) if ( p->pPars->fSemiFormal )
{ {
Aig_Man_t * pSRed; Aig_Man_t * pSRed;
Ssw_FilterUsingBmc( p, 0, 2000, p->pPars->fVerbose ); Ssw_FilterUsingSemi( p, 0, 2000, p->pPars->fVerbose );
// Ssw_FilterUsingBmc( p, 1, 100000, p->pPars->fVerbose ); // Ssw_FilterUsingSemi( p, 1, 100000, p->pPars->fVerbose );
pSRed = Ssw_SpeculativeReduction( p ); pSRed = Ssw_SpeculativeReduction( p );
Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL ); Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL );
Aig_ManStop( pSRed ); Aig_ManStop( pSRed );
} }
*/
// refine classes using induction // refine classes using induction
nSatProof = nSatCallsSat = nRecycles = nSatFailsReal = 0; nSatProof = nSatCallsSat = nRecycles = nSatFailsReal = 0;
for ( nIter = 0; ; nIter++ ) for ( nIter = 0; ; nIter++ )
{ {
clk = clock(); clk = clock();
p->pMSat = Ssw_SatStart( 0 );
if ( p->pPars->fLatchCorrOpt ) if ( p->pPars->fLatchCorrOpt )
{ {
RetValue = Ssw_ManSweepLatch( p ); RetValue = Ssw_ManSweepLatch( p );
...@@ -153,34 +161,32 @@ clk = clock(); ...@@ -153,34 +161,32 @@ clk = clock();
else else
{ {
RetValue = Ssw_ManSweep( p ); RetValue = Ssw_ManSweep( p );
p->pPars->nConflicts += p->pSat->stats.conflicts; p->pPars->nConflicts += p->pMSat->pSat->stats.conflicts;
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
{ {
printf( "%3d : Const = %6d. Cl = %6d. LR = %6d. NR = %6d. U = %3d. F = %2d. ", printf( "%3d : Const = %6d. Cl = %6d. LR = %6d. NR = %6d. U = %3d. F = %2d. ",
nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses), nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses),
p->nConstrReduced, Aig_ManNodeNum(p->pFrames), p->nUniques, p->nSatFailsReal ); p->nConstrReduced, Aig_ManNodeNum(p->pFrames), p->nUniques, p->nSatFailsReal );
if ( p->pPars->fSkipCheck )
printf( "Use = %5d. Skip = %5d. ",
p->nRefUse, p->nRefSkip );
PRT( "T", clock() - clk ); PRT( "T", clock() - clk );
} }
} }
Ssw_SatStop( p->pMSat );
p->pMSat = NULL;
Ssw_ManCleanup( p ); Ssw_ManCleanup( p );
if ( !RetValue ) if ( !RetValue )
break; break;
/*
if ( p->pPars->nItersStop && p->pPars->nItersStop == nIter )
{ {
static int Flag = 0; Aig_Man_t * pSRed = Ssw_SpeculativeReduction( p );
if ( Flag++ == 4 && nIter == 4 ) Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL );
{ Aig_ManStop( pSRed );
Aig_Man_t * pSRed; printf( "Iterative refinement is stopped after iteration %d.\n", nIter );
pSRed = Ssw_SpeculativeReduction( p ); printf( "The network is reduced using candidate equivalences.\n" );
Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL ); printf( "Speculatively reduced miter is saved in file \"%s\".\n", "srm.blif" );
Aig_ManStop( pSRed ); printf( "If the miter is SAT, the reduced result is incorrect.\n" );
} break;
} }
*/
} }
p->pPars->nIters = nIter + 1; p->pPars->nIters = nIter + 1;
p->timeTotal = clock() - clkTotal; p->timeTotal = clock() - clkTotal;
...@@ -224,6 +230,13 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) ...@@ -224,6 +230,13 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
return Aig_ManDupOrdered(pAig); return Aig_ManDupOrdered(pAig);
} }
// check and update parameters // check and update parameters
if ( pPars->fUniqueness )
{
pPars->nFramesAddSim = 0;
if ( pPars->nFramesK != 2 )
printf( "Setting K = 2 for uniqueness constaints to work.\n" );
pPars->nFramesK = 2;
}
if ( pPars->fLatchCorrOpt ) if ( pPars->fLatchCorrOpt )
{ {
pPars->fLatchCorr = 1; pPars->fLatchCorr = 1;
...@@ -232,8 +245,6 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) ...@@ -232,8 +245,6 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
else else
{ {
assert( pPars->nFramesK > 0 ); assert( pPars->nFramesK > 0 );
if ( pPars->nFramesK > 1 )
pPars->fSkipCheck = 0;
// perform partitioning // perform partitioning
if ( (pPars->nPartSize > 0 && pPars->nPartSize < Aig_ManRegNum(pAig)) if ( (pPars->nPartSize > 0 && pPars->nPartSize < Aig_ManRegNum(pAig))
|| (pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0) ) || (pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0) )
...@@ -259,6 +270,9 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) ...@@ -259,6 +270,9 @@ Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
} }
// perform refinement of classes // perform refinement of classes
pAigNew = Ssw_SignalCorrespondenceRefine( p ); pAigNew = Ssw_SignalCorrespondenceRefine( p );
if ( pPars->fUniqueness )
printf( "Uniqueness constaint = %3d. Prevented counter-examples = %3d.\n",
p->nUniquesAdded, p->nUniquesUseful );
// cleanup // cleanup
Ssw_ManStop( p ); Ssw_ManStop( p );
return pAigNew; return pAigNew;
......
...@@ -42,6 +42,8 @@ extern "C" { ...@@ -42,6 +42,8 @@ extern "C" {
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
typedef struct Ssw_Man_t_ Ssw_Man_t; // signal correspondence manager typedef struct Ssw_Man_t_ Ssw_Man_t; // signal correspondence manager
typedef struct Ssw_Frm_t_ Ssw_Frm_t; // unrolled frames manager
typedef struct Ssw_Sat_t_ Ssw_Sat_t; // SAT solver manager
typedef struct Ssw_Cla_t_ Ssw_Cla_t; // equivalence classe manager typedef struct Ssw_Cla_t_ Ssw_Cla_t; // equivalence classe manager
typedef struct Ssw_Sml_t_ Ssw_Sml_t; // sequential simulation manager typedef struct Ssw_Sml_t_ Ssw_Sml_t; // sequential simulation manager
...@@ -57,17 +59,10 @@ struct Ssw_Man_t_ ...@@ -57,17 +59,10 @@ struct Ssw_Man_t_
// equivalence classes // equivalence classes
Ssw_Cla_t * ppClasses; // equivalence classes of nodes Ssw_Cla_t * ppClasses; // equivalence classes of nodes
int fRefined; // is set to 1 when refinement happens int fRefined; // is set to 1 when refinement happens
int nRefUse; // the number of equivalences used // SAT solving
int nRefSkip; // the number of equivalences skipped Ssw_Sat_t * pMSatBmc; // SAT manager for base case
// SAT solving Ssw_Sat_t * pMSat; // SAT manager for inductive case
sat_solver * pSat; // recyclable SAT solver
int nSatVars; // the counter of SAT variables
Vec_Int_t * vSatVars; // mapping of each node into its SAT var
int nSatVarsTotal; // the total number of SAT vars created
Vec_Ptr_t * vFanins; // fanins of the CNF node
// SAT solving (latch corr only) // SAT solving (latch corr only)
Vec_Ptr_t * vUsedNodes; // the nodes with SAT variables
Vec_Ptr_t * vUsedPis; // the PIs with SAT variables
Vec_Ptr_t * vSimInfo; // simulation information for the framed PIs Vec_Ptr_t * vSimInfo; // simulation information for the framed PIs
int nPatterns; // the number of patterns saved int nPatterns; // the number of patterns saved
int nSimRounds; // the number of simulation rounds performed int nSimRounds; // the number of simulation rounds performed
...@@ -81,7 +76,10 @@ struct Ssw_Man_t_ ...@@ -81,7 +76,10 @@ struct Ssw_Man_t_
// uniqueness // uniqueness
Vec_Ptr_t * vCommon; // the set of common variables in the logic cones Vec_Ptr_t * vCommon; // the set of common variables in the logic cones
int iOutputLit; // the output literal of the uniqueness constaint int iOutputLit; // the output literal of the uniqueness constaint
Vec_Int_t * vDiffPairs; // is set to 1 if reg pair can be diff
int nUniques; // the number of uniqueness constaints used int nUniques; // the number of uniqueness constaints used
int nUniquesAdded; // useful uniqueness constraints
int nUniquesUseful; // useful uniqueness constraints
// sequential simulator // sequential simulator
Ssw_Sml_t * pSml; Ssw_Sml_t * pSml;
// counter example storage // counter example storage
...@@ -118,12 +116,35 @@ struct Ssw_Man_t_ ...@@ -118,12 +116,35 @@ struct Ssw_Man_t_
int timeTotal; // total runtime int timeTotal; // total runtime
}; };
// internal SAT manager
struct Ssw_Sat_t_
{
Aig_Man_t * pAig; // the AIG manager
int fPolarFlip; // flips polarity
sat_solver * pSat; // recyclable SAT solver
int nSatVars; // the counter of SAT variables
Vec_Int_t * vSatVars; // mapping of each node into its SAT var
int nSatVarsTotal; // the total number of SAT vars created
Vec_Ptr_t * vFanins; // fanins of the CNF node
Vec_Ptr_t * vUsedPis; // the PIs with SAT variables
};
// internal frames manager
struct Ssw_Frm_t_
{
Aig_Man_t * pAig; // user-given AIG
int nObjs; // offset in terms of AIG nodes
int nFrames; // the number of frames in current unrolling
Aig_Man_t * pFrames; // unrolled AIG
Vec_Ptr_t * vAig2Frm; // mapping of AIG nodes into frame nodes
};
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS /// /// MACRO DEFINITIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
static inline int Ssw_ObjSatNum( Ssw_Man_t * p, Aig_Obj_t * pObj ) { return Vec_IntEntry( p->vSatVars, pObj->Id ); } static inline int Ssw_ObjSatNum( Ssw_Sat_t * p, Aig_Obj_t * pObj ) { return Vec_IntGetEntry( p->vSatVars, pObj->Id ); }
static inline void Ssw_ObjSetSatNum( Ssw_Man_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntWriteEntryFill( p->vSatVars, pObj->Id, Num ); } static inline void Ssw_ObjSetSatNum( Ssw_Sat_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntSetEntry(p->vSatVars, pObj->Id, Num); }
static inline int Ssw_ObjIsConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj ) static inline int Ssw_ObjIsConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )
{ {
...@@ -141,15 +162,22 @@ static inline void Ssw_ObjSetFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int ...@@ -141,15 +162,22 @@ static inline void Ssw_ObjSetFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int
static inline Aig_Obj_t * Ssw_ObjChild0Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)) : NULL; } static inline Aig_Obj_t * Ssw_ObjChild0Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)) : NULL; }
static inline Aig_Obj_t * Ssw_ObjChild1Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)) : NULL; } static inline Aig_Obj_t * Ssw_ObjChild1Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)) : NULL; }
static inline Aig_Obj_t * Ssw_ObjFrame_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i ) { return Vec_PtrGetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id ); }
static inline void Ssw_ObjSetFrame_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { Vec_PtrSetEntry( p->vAig2Frm, p->nObjs*i+pObj->Id, pNode ); }
static inline Aig_Obj_t * Ssw_ObjChild0Fra_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Ssw_ObjFrame_(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)) : NULL; }
static inline Aig_Obj_t * Ssw_ObjChild1Fra_( Ssw_Frm_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Ssw_ObjFrame_(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)) : NULL; }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS /// /// FUNCTION DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/*=== sswAig.c ===================================================*/ /*=== sswAig.c ===================================================*/
extern Ssw_Frm_t * Ssw_FrmStart( Aig_Man_t * pAig );
extern void Ssw_FrmStop( Ssw_Frm_t * p );
extern Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p ); extern Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p );
extern Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p ); extern Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p );
/*=== sswBmc.c ===================================================*/ /*=== sswBmc.c ===================================================*/
extern int Ssw_FilterUsingBmc( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose );
/*=== sswClass.c =================================================*/ /*=== sswClass.c =================================================*/
extern Ssw_Cla_t * Ssw_ClassesStart( Aig_Man_t * pAig ); extern Ssw_Cla_t * Ssw_ClassesStart( Aig_Man_t * pAig );
extern void Ssw_ClassesSetData( Ssw_Cla_t * p, void * pManData, extern void Ssw_ClassesSetData( Ssw_Cla_t * p, void * pManData,
...@@ -177,7 +205,10 @@ extern int Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr ...@@ -177,7 +205,10 @@ extern int Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr
extern int Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecursive ); extern int Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecursive );
extern int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive ); extern int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive );
/*=== sswCnf.c ===================================================*/ /*=== sswCnf.c ===================================================*/
extern void Ssw_CnfNodeAddToSolver( Ssw_Man_t * p, Aig_Obj_t * pObj ); extern Ssw_Sat_t * Ssw_SatStart( int fPolarFlip );
extern void Ssw_SatStop( Ssw_Sat_t * p );
extern void Ssw_CnfNodeAddToSolver( Ssw_Sat_t * p, Aig_Obj_t * pObj );
extern int Ssw_CnfGetNodeValue( Ssw_Sat_t * p, Aig_Obj_t * pObjFraig );
/*=== sswCore.c ===================================================*/ /*=== sswCore.c ===================================================*/
extern Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p ); extern Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p );
/*=== sswLcorr.c ==========================================================*/ /*=== sswLcorr.c ==========================================================*/
...@@ -190,6 +221,8 @@ extern void Ssw_ManStartSolver( Ssw_Man_t * p ); ...@@ -190,6 +221,8 @@ extern void Ssw_ManStartSolver( Ssw_Man_t * p );
/*=== sswSat.c ===================================================*/ /*=== sswSat.c ===================================================*/
extern int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ); extern int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
extern int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ); extern int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
/*=== sswSemi.c ===================================================*/
extern int Ssw_FilterUsingSemi( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose );
/*=== sswSim.c ===================================================*/ /*=== sswSim.c ===================================================*/
extern unsigned Ssw_SmlObjHashWord( Ssw_Sml_t * p, Aig_Obj_t * pObj ); extern unsigned Ssw_SmlObjHashWord( Ssw_Sml_t * p, Aig_Obj_t * pObj );
extern int Ssw_SmlObjIsConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj ); extern int Ssw_SmlObjIsConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj );
...@@ -214,6 +247,7 @@ extern int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, i ...@@ -214,6 +247,7 @@ extern int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, i
extern int Ssw_ManSweepBmc( Ssw_Man_t * p ); extern int Ssw_ManSweepBmc( Ssw_Man_t * p );
extern int Ssw_ManSweep( Ssw_Man_t * p ); extern int Ssw_ManSweep( Ssw_Man_t * p );
/*=== sswUnique.c ===================================================*/ /*=== sswUnique.c ===================================================*/
extern void Ssw_UniqueRegisterPairInfo( Ssw_Man_t * p );
extern int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj ); extern int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj );
extern int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 ); extern int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 );
......
...@@ -31,48 +31,6 @@ ...@@ -31,48 +31,6 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [Recycles the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManSatSolverRecycle( Ssw_Man_t * p )
{
int Lit;
if ( p->pSat )
{
Aig_Obj_t * pObj;
int i;
Vec_PtrForEachEntry( p->vUsedNodes, pObj, i )
Ssw_ObjSetSatNum( p, pObj, 0 );
Vec_PtrClear( p->vUsedNodes );
Vec_PtrClear( p->vUsedPis );
// memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAigTotal) );
sat_solver_delete( p->pSat );
}
p->pSat = sat_solver_new();
sat_solver_setnvars( p->pSat, 1000 );
// var 0 is not used
// var 1 is reserved for const1 node - add the clause
p->nSatVars = 1;
// p->nSatVars = 0;
Lit = toLit( p->nSatVars );
if ( p->pPars->fPolarFlip )
Lit = lit_neg( Lit );
sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
Ssw_ObjSetSatNum( p, Aig_ManConst1(p->pFrames), p->nSatVars++ );
p->nRecycles++;
p->nRecycleCalls = 0;
}
/**Function*************************************************************
Synopsis [Tranfers simulation information from FRAIG to AIG.] Synopsis [Tranfers simulation information from FRAIG to AIG.]
Description [] Description []
...@@ -148,11 +106,11 @@ void Ssw_SmlAddPattern( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pCand ) ...@@ -148,11 +106,11 @@ void Ssw_SmlAddPattern( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pCand )
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
unsigned * pInfo; unsigned * pInfo;
int i, nVarNum, Value; int i, nVarNum, Value;
Vec_PtrForEachEntry( p->vUsedPis, pObj, i ) Vec_PtrForEachEntry( p->pMSat->vUsedPis, pObj, i )
{ {
nVarNum = Ssw_ObjSatNum( p, pObj ); nVarNum = Ssw_ObjSatNum( p->pMSat, pObj );
assert( nVarNum > 0 ); assert( nVarNum > 0 );
Value = sat_solver_var_value( p->pSat, nVarNum ); Value = sat_solver_var_value( p->pMSat->pSat, nVarNum );
if ( Value == 0 ) if ( Value == 0 )
continue; continue;
pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) ); pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) );
...@@ -339,9 +297,14 @@ int Ssw_ManSweepLatch( Ssw_Man_t * p ) ...@@ -339,9 +297,14 @@ int Ssw_ManSweepLatch( Ssw_Man_t * p )
Ssw_ManSweepResimulate( p ); Ssw_ManSweepResimulate( p );
// attempt recycling the SAT solver // attempt recycling the SAT solver
if ( p->pPars->nSatVarMax && if ( p->pPars->nSatVarMax &&
p->nSatVars > p->pPars->nSatVarMax && p->pMSat->nSatVars > p->pPars->nSatVarMax &&
p->nRecycleCalls > p->pPars->nRecycleCalls ) p->nRecycleCalls > p->pPars->nRecycleCalls )
Ssw_ManSatSolverRecycle( p ); {
Ssw_SatStop( p->pMSat );
p->pMSat = Ssw_SatStart( 0 );
p->nRecycles++;
p->nRecycleCalls = 0;
}
} }
// resimulate // resimulate
if ( p->nPatterns > 0 ) if ( p->nPatterns > 0 )
......
...@@ -53,12 +53,6 @@ Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars ) ...@@ -53,12 +53,6 @@ Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
p->pAig = pAig; p->pAig = pAig;
p->nFrames = pPars->nFramesK + 1; p->nFrames = pPars->nFramesK + 1;
p->pNodeToFrames = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) * p->nFrames ); p->pNodeToFrames = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) * p->nFrames );
// SAT solving
p->vSatVars = Vec_IntStart( Aig_ManObjNumMax(p->pAig) * (p->nFrames+1) );
p->vFanins = Vec_PtrAlloc( 100 );
// SAT solving (latch corr only)
p->vUsedNodes = Vec_PtrAlloc( 1000 );
p->vUsedPis = Vec_PtrAlloc( 1000 );
p->vCommon = Vec_PtrAlloc( 100 ); p->vCommon = Vec_PtrAlloc( 100 );
p->iOutputLit = -1; p->iOutputLit = -1;
// allocate storage for sim pattern // allocate storage for sim pattern
...@@ -106,11 +100,11 @@ void Ssw_ManPrintStats( Ssw_Man_t * p ) ...@@ -106,11 +100,11 @@ void Ssw_ManPrintStats( Ssw_Man_t * p )
p->pPars->nFramesK, p->pPars->nFramesAddSim, p->pPars->nBTLimit, p->pPars->nConstrs, p->pPars->nMaxLevs, nMemory ); p->pPars->nFramesK, p->pPars->nFramesAddSim, p->pPars->nBTLimit, p->pPars->nConstrs, p->pPars->nMaxLevs, nMemory );
printf( "AIG : PI = %d. PO = %d. Latch = %d. Node = %d. Ave SAT vars = %d.\n", printf( "AIG : PI = %d. PO = %d. Latch = %d. Node = %d. Ave SAT vars = %d.\n",
Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), Saig_ManRegNum(p->pAig), Aig_ManNodeNum(p->pAig), Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), Saig_ManRegNum(p->pAig), Aig_ManNodeNum(p->pAig),
p->nSatVarsTotal/p->pPars->nIters ); 0/p->pPars->nIters );
printf( "SAT calls : Proof = %d. Cex = %d. Fail = %d. Equivs = %d. Str = %d.\n", printf( "SAT calls : Proof = %d. Cex = %d. Fail = %d. Equivs = %d. Str = %d.\n",
p->nSatProof, p->nSatCallsSat, p->nSatFailsTotal, Ssw_ManCountEquivs(p), p->nStrangers ); p->nSatProof, p->nSatCallsSat, p->nSatFailsTotal, Ssw_ManCountEquivs(p), p->nStrangers );
printf( "SAT solver: Vars = %d. Max cone = %d. Recycles = %d. Rounds = %d.\n", printf( "SAT solver: Vars = %d. Max cone = %d. Recycles = %d. Rounds = %d.\n",
p->nSatVars, p->nConeMax, p->nRecycles, p->nSimRounds ); 0, p->nConeMax, p->nRecycles, p->nSimRounds );
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:1), p->nNodesBeg, p->nNodesEnd, 100.0*(p->nNodesBeg-p->nNodesEnd)/(p->nNodesBeg?p->nNodesBeg:1),
p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/(p->nRegsBeg?p->nRegsBeg:1) ); p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/(p->nRegsBeg?p->nRegsBeg:1) );
...@@ -141,23 +135,14 @@ void Ssw_ManPrintStats( Ssw_Man_t * p ) ...@@ -141,23 +135,14 @@ void Ssw_ManPrintStats( Ssw_Man_t * p )
***********************************************************************/ ***********************************************************************/
void Ssw_ManCleanup( Ssw_Man_t * p ) void Ssw_ManCleanup( Ssw_Man_t * p )
{ {
assert( p->pMSat == NULL );
if ( p->pFrames ) if ( p->pFrames )
{ {
Aig_ManCleanMarkA( p->pFrames );
Aig_ManStop( p->pFrames ); Aig_ManStop( p->pFrames );
p->pFrames = NULL; p->pFrames = NULL;
memset( p->pNodeToFrames, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(p->pAig) * p->nFrames ); memset( p->pNodeToFrames, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(p->pAig) * p->nFrames );
} }
if ( p->pSat )
{
int i;
// printf( "Vars = %d. Clauses = %d. Learnts = %d.\n", p->pSat->size, p->pSat->clauses.size, p->pSat->learnts.size );
p->nSatVarsTotal += p->pSat->size;
sat_solver_delete( p->pSat );
p->pSat = NULL;
// memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAig) * (p->nFrames+1) );
for ( i = 0; i < Vec_IntSize(p->vSatVars); i++ )
p->vSatVars->pArray[i] = 0;
}
if ( p->vSimInfo ) if ( p->vSimInfo )
{ {
Vec_PtrFree( p->vSimInfo ); Vec_PtrFree( p->vSimInfo );
...@@ -188,46 +173,14 @@ void Ssw_ManStop( Ssw_Man_t * p ) ...@@ -188,46 +173,14 @@ void Ssw_ManStop( Ssw_Man_t * p )
Ssw_ClassesStop( p->ppClasses ); Ssw_ClassesStop( p->ppClasses );
if ( p->pSml ) if ( p->pSml )
Ssw_SmlStop( p->pSml ); Ssw_SmlStop( p->pSml );
Vec_PtrFree( p->vFanins ); if ( p->vDiffPairs )
Vec_PtrFree( p->vUsedNodes ); Vec_IntFree( p->vDiffPairs );
Vec_PtrFree( p->vUsedPis );
Vec_IntFree( p->vSatVars );
Vec_PtrFree( p->vCommon ); Vec_PtrFree( p->vCommon );
FREE( p->pNodeToFrames ); FREE( p->pNodeToFrames );
FREE( p->pPatWords ); FREE( p->pPatWords );
free( p ); free( p );
} }
/**Function*************************************************************
Synopsis [Starts the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManStartSolver( Ssw_Man_t * p )
{
int Lit;
assert( p->pSat == NULL );
p->pSat = sat_solver_new();
sat_solver_setnvars( p->pSat, 1000 );
// var 0 is not used
// var 1 is reserved for const1 node - add the clause
p->nSatVars = 1;
Lit = toLit( p->nSatVars );
if ( p->pPars->fPolarFlip )
Lit = lit_neg( Lit );
sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
Ssw_ObjSetSatNum( p, Aig_ManConst1(p->pAig), p->nSatVars++ );
Vec_PtrClear( p->vUsedNodes );
Vec_PtrClear( p->vUsedPis );
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
/// END OF FILE /// /// END OF FILE ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
......
...@@ -50,18 +50,19 @@ int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) ...@@ -50,18 +50,19 @@ int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
assert( !Aig_IsComplement(pNew) ); assert( !Aig_IsComplement(pNew) );
assert( pOld != pNew ); assert( pOld != pNew );
if ( p->pSat == NULL ) // if ( p->pSat == NULL )
Ssw_ManStartSolver( p ); // Ssw_ManStartSolver( p );
assert( p->pMSat != NULL );
// if the nodes do not have SAT variables, allocate them // if the nodes do not have SAT variables, allocate them
Ssw_CnfNodeAddToSolver( p, pOld ); Ssw_CnfNodeAddToSolver( p->pMSat, pOld );
Ssw_CnfNodeAddToSolver( p, pNew ); Ssw_CnfNodeAddToSolver( p->pMSat, pNew );
// solve under assumptions // solve under assumptions
// A = 1; B = 0 OR A = 1; B = 1 // A = 1; B = 0 OR A = 1; B = 1
nLits = 2; nLits = 2;
pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 0 ); pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 0 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), pOld->fPhase == pNew->fPhase ); pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), pOld->fPhase == pNew->fPhase );
if ( p->iOutputLit > -1 ) if ( p->iOutputLit > -1 )
pLits[nLits++] = p->iOutputLit; pLits[nLits++] = p->iOutputLit;
if ( p->pPars->fPolarFlip ) if ( p->pPars->fPolarFlip )
...@@ -71,14 +72,14 @@ int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) ...@@ -71,14 +72,14 @@ int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
} }
//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 ); //Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
if ( p->pSat->qtail != p->pSat->qhead ) if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
{ {
RetValue = sat_solver_simplify(p->pSat); RetValue = sat_solver_simplify(p->pMSat->pSat);
assert( RetValue != 0 ); assert( RetValue != 0 );
} }
clk = clock(); clk = clock();
RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + nLits, RetValue1 = sat_solver_solve( p->pMSat->pSat, pLits, pLits + nLits,
(sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 ); (sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
p->timeSat += clock() - clk; p->timeSat += clock() - clk;
if ( RetValue1 == l_False ) if ( RetValue1 == l_False )
...@@ -88,8 +89,15 @@ p->timeSatUnsat += clock() - clk; ...@@ -88,8 +89,15 @@ p->timeSatUnsat += clock() - clk;
{ {
pLits[0] = lit_neg( pLits[0] ); pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] ); pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
assert( RetValue ); assert( RetValue );
/*
if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
{
RetValue = sat_solver_simplify(p->pMSat->pSat);
assert( RetValue != 0 );
}
*/
} }
p->nSatCallsUnsat++; p->nSatCallsUnsat++;
} }
...@@ -116,8 +124,8 @@ p->timeSatUndec += clock() - clk; ...@@ -116,8 +124,8 @@ p->timeSatUndec += clock() - clk;
// solve under assumptions // solve under assumptions
// A = 0; B = 1 OR A = 0; B = 0 // A = 0; B = 1 OR A = 0; B = 0
nLits = 2; nLits = 2;
pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 1 ); pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 1 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), pOld->fPhase ^ pNew->fPhase ); pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), pOld->fPhase ^ pNew->fPhase );
if ( p->iOutputLit > -1 ) if ( p->iOutputLit > -1 )
pLits[nLits++] = p->iOutputLit; pLits[nLits++] = p->iOutputLit;
if ( p->pPars->fPolarFlip ) if ( p->pPars->fPolarFlip )
...@@ -126,14 +134,14 @@ p->timeSatUndec += clock() - clk; ...@@ -126,14 +134,14 @@ p->timeSatUndec += clock() - clk;
if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] ); if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
} }
if ( p->pSat->qtail != p->pSat->qhead ) if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
{ {
RetValue = sat_solver_simplify(p->pSat); RetValue = sat_solver_simplify(p->pMSat->pSat);
assert( RetValue != 0 ); assert( RetValue != 0 );
} }
clk = clock(); clk = clock();
RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + nLits, RetValue1 = sat_solver_solve( p->pMSat->pSat, pLits, pLits + nLits,
(sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 ); (sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
p->timeSat += clock() - clk; p->timeSat += clock() - clk;
if ( RetValue1 == l_False ) if ( RetValue1 == l_False )
...@@ -143,8 +151,15 @@ p->timeSatUnsat += clock() - clk; ...@@ -143,8 +151,15 @@ p->timeSatUnsat += clock() - clk;
{ {
pLits[0] = lit_neg( pLits[0] ); pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] ); pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
assert( RetValue ); assert( RetValue );
/*
if ( p->pMSat->pSat->qtail != p->pMSat->pSat->qhead )
{
RetValue = sat_solver_simplify(p->pMSat->pSat);
assert( RetValue != 0 );
}
*/
} }
p->nSatCallsUnsat++; p->nSatCallsUnsat++;
} }
...@@ -183,6 +198,7 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) ...@@ -183,6 +198,7 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
// sanity checks // sanity checks
assert( Aig_Regular(pOld) != Aig_Regular(pNew) ); assert( Aig_Regular(pOld) != Aig_Regular(pNew) );
assert( Aig_ObjPhaseReal(pOld) == Aig_ObjPhaseReal(pNew) );
// move constant to the old node // move constant to the old node
if ( Aig_Regular(pNew) == Aig_ManConst1(p->pFrames) ) if ( Aig_Regular(pNew) == Aig_ManConst1(p->pFrames) )
...@@ -200,13 +216,13 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) ...@@ -200,13 +216,13 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
pNew = Aig_Not(pNew); pNew = Aig_Not(pNew);
} }
// start the solver // if ( p->pSat == NULL )
if ( p->pSat == NULL ) // Ssw_ManStartSolver( p );
Ssw_ManStartSolver( p ); assert( p->pMSat != NULL );
// if the nodes do not have SAT variables, allocate them // if the nodes do not have SAT variables, allocate them
Ssw_CnfNodeAddToSolver( p, pOld ); Ssw_CnfNodeAddToSolver( p->pMSat, pOld );
Ssw_CnfNodeAddToSolver( p, Aig_Regular(pNew) ); Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pNew) );
// transform the new node // transform the new node
fComplNew = Aig_IsComplement( pNew ); fComplNew = Aig_IsComplement( pNew );
...@@ -216,12 +232,12 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) ...@@ -216,12 +232,12 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
if ( pOld == Aig_ManConst1(p->pFrames) ) if ( pOld == Aig_ManConst1(p->pFrames) )
{ {
// add constaint A = 1 ----> A // add constaint A = 1 ----> A
pLits[0] = toLitCond( Ssw_ObjSatNum(p,pNew), fComplNew ); pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), fComplNew );
if ( p->pPars->fPolarFlip ) if ( p->pPars->fPolarFlip )
{ {
if ( pNew->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pNew->fPhase ) pLits[0] = lit_neg( pLits[0] );
} }
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 ); RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 1 );
assert( RetValue ); assert( RetValue );
} }
else else
...@@ -229,8 +245,8 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) ...@@ -229,8 +245,8 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
// add constaint A = B ----> (A v !B)(!A v B) // add constaint A = B ----> (A v !B)(!A v B)
// (A v !B) // (A v !B)
pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 0 ); pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 0 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), !fComplNew ); pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), !fComplNew );
if ( p->pPars->fPolarFlip ) if ( p->pPars->fPolarFlip )
{ {
if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
...@@ -238,12 +254,12 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) ...@@ -238,12 +254,12 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
} }
pLits[0] = lit_neg( pLits[0] ); pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] ); pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
assert( RetValue ); assert( RetValue );
// (!A v B) // (!A v B)
pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 1 ); pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,pOld), 1 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), fComplNew); pLits[1] = toLitCond( Ssw_ObjSatNum(p->pMSat,pNew), fComplNew);
if ( p->pPars->fPolarFlip ) if ( p->pPars->fPolarFlip )
{ {
if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] ); if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
...@@ -251,7 +267,7 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew ) ...@@ -251,7 +267,7 @@ int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
} }
pLits[0] = lit_neg( pLits[0] ); pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] ); pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 ); RetValue = sat_solver_addclause( p->pMSat->pSat, pLits, pLits + 2 );
assert( RetValue ); assert( RetValue );
} }
return 1; return 1;
......
/**CFile**************************************************************** /**CFile****************************************************************
FileName [sswBmc.c] FileName [sswSemi.c]
SystemName [ABC: Logic synthesis and verification system.] SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.] PackageName [Inductive prover with constraints.]
Synopsis [Bounded model checker for equivalence clases.] Synopsis [Semiformal for equivalence clases.]
Author [Alan Mishchenko] Author [Alan Mishchenko]
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
Date [Ver. 1.0. Started - September 1, 2008.] Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswBmc.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $] Revision [$Id: sswSemi.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/ ***********************************************************************/
...@@ -24,9 +24,9 @@ ...@@ -24,9 +24,9 @@
/// DECLARATIONS /// /// DECLARATIONS ///
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
typedef struct Ssw_Bmc_t_ Ssw_Bmc_t; // BMC manager typedef struct Ssw_Sem_t_ Ssw_Sem_t; // BMC manager
struct Ssw_Bmc_t_ struct Ssw_Sem_t_
{ {
// parameters // parameters
int nConfMaxStart; // the starting conflict limit int nConfMaxStart; // the starting conflict limit
...@@ -58,14 +58,14 @@ struct Ssw_Bmc_t_ ...@@ -58,14 +58,14 @@ struct Ssw_Bmc_t_
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
Ssw_Bmc_t * Ssw_BmcManStart( Ssw_Man_t * pMan, int nConfMax, int fVerbose ) Ssw_Sem_t * Ssw_SemManStart( Ssw_Man_t * pMan, int nConfMax, int fVerbose )
{ {
Ssw_Bmc_t * p; Ssw_Sem_t * p;
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
int i; int i;
// create interpolation manager // create interpolation manager
p = ALLOC( Ssw_Bmc_t, 1 ); p = ALLOC( Ssw_Sem_t, 1 );
memset( p, 0, sizeof(Ssw_Bmc_t) ); memset( p, 0, sizeof(Ssw_Sem_t) );
p->nConfMaxStart = nConfMax; p->nConfMaxStart = nConfMax;
p->nConfMax = nConfMax; p->nConfMax = nConfMax;
p->nFramesSweep = AIG_MAX( (1<<21)/Aig_ManNodeNum(pMan->pAig), pMan->nFrames ); p->nFramesSweep = AIG_MAX( (1<<21)/Aig_ManNodeNum(pMan->pAig), pMan->nFrames );
...@@ -83,10 +83,13 @@ Ssw_Bmc_t * Ssw_BmcManStart( Ssw_Man_t * pMan, int nConfMax, int fVerbose ) ...@@ -83,10 +83,13 @@ Ssw_Bmc_t * Ssw_BmcManStart( Ssw_Man_t * pMan, int nConfMax, int fVerbose )
p->vHistory = Vec_IntAlloc( 100 ); p->vHistory = Vec_IntAlloc( 100 );
Vec_IntPush( p->vHistory, 0 ); Vec_IntPush( p->vHistory, 0 );
// update arrays of the manager // update arrays of the manager
assert( 0 );
/*
free( p->pMan->pNodeToFrames ); free( p->pMan->pNodeToFrames );
Vec_IntFree( p->pMan->vSatVars ); Vec_IntFree( p->pMan->vSatVars );
p->pMan->pNodeToFrames = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pMan->pAig) * p->nFramesSweep ); p->pMan->pNodeToFrames = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pMan->pAig) * p->nFramesSweep );
p->pMan->vSatVars = Vec_IntStart( Aig_ManObjNumMax(p->pMan->pAig) * (p->nFramesSweep+1) ); p->pMan->vSatVars = Vec_IntStart( Aig_ManObjNumMax(p->pMan->pAig) * (p->nFramesSweep+1) );
*/
return p; return p;
} }
...@@ -101,7 +104,7 @@ Ssw_Bmc_t * Ssw_BmcManStart( Ssw_Man_t * pMan, int nConfMax, int fVerbose ) ...@@ -101,7 +104,7 @@ Ssw_Bmc_t * Ssw_BmcManStart( Ssw_Man_t * pMan, int nConfMax, int fVerbose )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Ssw_BmcManStop( Ssw_Bmc_t * p ) void Ssw_SemManStop( Ssw_Sem_t * p )
{ {
Vec_PtrFree( p->vTargets ); Vec_PtrFree( p->vTargets );
Vec_PtrFree( p->vPatterns ); Vec_PtrFree( p->vPatterns );
...@@ -120,7 +123,7 @@ void Ssw_BmcManStop( Ssw_Bmc_t * p ) ...@@ -120,7 +123,7 @@ void Ssw_BmcManStop( Ssw_Bmc_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ssw_BmcCheckTargets( Ssw_Bmc_t * p ) int Ssw_SemCheckTargets( Ssw_Sem_t * p )
{ {
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
int i; int i;
...@@ -141,7 +144,7 @@ int Ssw_BmcCheckTargets( Ssw_Bmc_t * p ) ...@@ -141,7 +144,7 @@ int Ssw_BmcCheckTargets( Ssw_Bmc_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
void Ssw_ManFilterBmcSavePattern( Ssw_Bmc_t * p ) void Ssw_ManFilterBmcSavePattern( Ssw_Sem_t * p )
{ {
unsigned * pInfo; unsigned * pInfo;
Aig_Obj_t * pObj; Aig_Obj_t * pObj;
...@@ -168,7 +171,7 @@ void Ssw_ManFilterBmcSavePattern( Ssw_Bmc_t * p ) ...@@ -168,7 +171,7 @@ void Ssw_ManFilterBmcSavePattern( Ssw_Bmc_t * p )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ssw_ManFilterBmc( Ssw_Bmc_t * pBmc, int iPat, int fCheckTargets ) int Ssw_ManFilterBmc( Ssw_Sem_t * pBmc, int iPat, int fCheckTargets )
{ {
Ssw_Man_t * p = pBmc->pMan; Ssw_Man_t * p = pBmc->pMan;
Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo; Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
...@@ -186,7 +189,6 @@ clk = clock(); ...@@ -186,7 +189,6 @@ clk = clock();
} }
// sweep internal nodes // sweep internal nodes
Ssw_ManStartSolver( p );
RetValue = pBmc->nFramesSweep; RetValue = pBmc->nFramesSweep;
for ( f = 0; f < pBmc->nFramesSweep; f++ ) for ( f = 0; f < pBmc->nFramesSweep; f++ )
{ {
...@@ -208,19 +210,19 @@ clk = clock(); ...@@ -208,19 +210,19 @@ clk = clock();
pBmc->nConfMax *= 10; pBmc->nConfMax *= 10;
} }
} }
if ( f > 0 && p->pSat->stats.conflicts >= pBmc->nConfMax ) if ( f > 0 && p->pMSat->pSat->stats.conflicts >= pBmc->nConfMax )
{ {
RetValue = -1; RetValue = -1;
break; break;
} }
} }
// quit if this is the last timeframe // quit if this is the last timeframe
if ( p->pSat->stats.conflicts >= pBmc->nConfMax ) if ( p->pMSat->pSat->stats.conflicts >= pBmc->nConfMax )
{ {
RetValue += f + 1; RetValue += f + 1;
break; break;
} }
if ( fCheckTargets && Ssw_BmcCheckTargets( pBmc ) ) if ( fCheckTargets && Ssw_SemCheckTargets( pBmc ) )
break; break;
// transfer latch input to the latch outputs // transfer latch input to the latch outputs
// build logic cones for register outputs // build logic cones for register outputs
...@@ -228,7 +230,7 @@ clk = clock(); ...@@ -228,7 +230,7 @@ clk = clock();
{ {
pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f); pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f);
Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew ); Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) ); Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );
} }
//printf( "Frame %2d : Conflicts = %6d. \n", f, p->pSat->stats.conflicts ); //printf( "Frame %2d : Conflicts = %6d. \n", f, p->pSat->stats.conflicts );
} }
...@@ -252,15 +254,15 @@ p->timeBmc += clock() - clk; ...@@ -252,15 +254,15 @@ p->timeBmc += clock() - clk;
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ssw_FilterUsingBmc( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose ) int Ssw_FilterUsingSemi( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose )
{ {
Ssw_Bmc_t * p; Ssw_Sem_t * p;
int RetValue, Frames, Iter, clk = clock(); int RetValue, Frames, Iter, clk = clock();
p = Ssw_BmcManStart( pMan, nConfMax, fVerbose ); p = Ssw_SemManStart( pMan, nConfMax, fVerbose );
if ( fCheckTargets && Ssw_BmcCheckTargets( p ) ) if ( fCheckTargets && Ssw_SemCheckTargets( p ) )
{ {
assert( 0 ); assert( 0 );
Ssw_BmcManStop( p ); Ssw_SemManStop( p );
return 1; return 1;
} }
if ( fVerbose ) if ( fVerbose )
...@@ -273,17 +275,18 @@ int Ssw_FilterUsingBmc( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int f ...@@ -273,17 +275,18 @@ int Ssw_FilterUsingBmc( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int f
for ( Iter = 0; Iter < p->nPatterns; Iter++ ) for ( Iter = 0; Iter < p->nPatterns; Iter++ )
{ {
clk = clock(); clk = clock();
pMan->pMSat = Ssw_SatStart( 0 );
Frames = Ssw_ManFilterBmc( p, Iter, fCheckTargets ); Frames = Ssw_ManFilterBmc( p, Iter, fCheckTargets );
if ( fVerbose ) if ( fVerbose )
{ {
printf( "%3d : Const = %6d. Cl = %6d. NR = %6d. F = %3d. C = %5d. P = %3d. %s ", printf( "%3d : Const = %6d. Cl = %6d. NR = %6d. F = %3d. C = %5d. P = %3d. %s ",
Iter, Ssw_ClassesCand1Num(p->pMan->ppClasses), Ssw_ClassesClassNum(p->pMan->ppClasses), Iter, Ssw_ClassesCand1Num(p->pMan->ppClasses), Ssw_ClassesClassNum(p->pMan->ppClasses),
Aig_ManNodeNum(p->pMan->pFrames), Frames, (int)p->pMan->pSat->stats.conflicts, p->nPatterns, Aig_ManNodeNum(p->pMan->pFrames), Frames, (int)p->pMan->pMSat->pSat->stats.conflicts, p->nPatterns,
p->pMan->nSatFailsReal? "f" : " " ); p->pMan->nSatFailsReal? "f" : " " );
PRT( "T", clock() - clk ); PRT( "T", clock() - clk );
} }
Ssw_ManCleanup( p->pMan ); Ssw_ManCleanup( p->pMan );
if ( fCheckTargets && Ssw_BmcCheckTargets( p ) ) if ( fCheckTargets && Ssw_SemCheckTargets( p ) )
{ {
printf( "Target is hit!!!\n" ); printf( "Target is hit!!!\n" );
RetValue = 1; RetValue = 1;
...@@ -291,7 +294,7 @@ clk = clock(); ...@@ -291,7 +294,7 @@ clk = clock();
if ( p->nPatterns >= p->nPatternsAlloc ) if ( p->nPatterns >= p->nPatternsAlloc )
break; break;
} }
Ssw_BmcManStop( p ); Ssw_SemManStop( p );
pMan->nStrangers = 0; pMan->nStrangers = 0;
pMan->nSatCalls = 0; pMan->nSatCalls = 0;
......
...@@ -271,45 +271,6 @@ void Ssw_SmlSavePattern1( Ssw_Man_t * p, int fInit ) ...@@ -271,45 +271,6 @@ void Ssw_SmlSavePattern1( Ssw_Man_t * p, int fInit )
Aig_InfoXorBit( p->pPatWords, nTruePis * p->nFrames + k++ ); Aig_InfoXorBit( p->pPatWords, nTruePis * p->nFrames + k++ );
} }
/**Function*************************************************************
Synopsis [Copy pattern from the solver into the internal storage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlSavePattern( Ssw_Man_t * p )
{
Aig_Obj_t * pObj;
int i;
memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
Aig_ManForEachPi( p->pFrames, pObj, i )
if ( p->pSat->model.ptr[Ssw_ObjSatNum(p, pObj)] == l_True )
Aig_InfoSetBit( p->pPatWords, i );
/*
if ( p->vCex )
{
Vec_IntClear( p->vCex );
for ( i = 0; i < Saig_ManPiNum(p->pAig); i++ )
Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) );
for ( i = Saig_ManPiNum(p->pFrames); i < Aig_ManPiNum(p->pFrames); i++ )
Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) );
}
*/
/*
printf( "Pattern: " );
Aig_ManForEachPi( p->pFrames, pObj, i )
printf( "%d", Aig_InfoHasBit( p->pPatWords, i ) );
printf( "\n" );
*/
}
/**Function************************************************************* /**Function*************************************************************
......
...@@ -31,53 +31,6 @@ ...@@ -31,53 +31,6 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [Mark nodes affected by sweep in the previous iteration.]
Description [Assumes that affected nodes are in p->ppClasses->vRefined.]
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManSweepMarkRefinement( Ssw_Man_t * p )
{
Vec_Ptr_t * vRefined, * vSupp;
Aig_Obj_t * pObj, * pObjLo, * pObjLi;
int i, k;
vRefined = Ssw_ClassesGetRefined( p->ppClasses );
if ( Vec_PtrSize(vRefined) == 0 )
{
Aig_ManForEachObj( p->pAig, pObj, i )
pObj->fMarkA = 1;
return;
}
// mark the nodes to be refined
Aig_ManCleanMarkA( p->pAig );
Vec_PtrForEachEntry( vRefined, pObj, i )
{
if ( Aig_ObjIsPi(pObj) )
{
pObj->fMarkA = 1;
continue;
}
assert( Aig_ObjIsNode(pObj) );
vSupp = Aig_Support( p->pAig, pObj );
Vec_PtrForEachEntry( vSupp, pObjLo, k )
pObjLo->fMarkA = 1;
Vec_PtrFree( vSupp );
}
// mark refinement
Aig_ManForEachNode( p->pAig, pObj, i )
pObj->fMarkA = Aig_ObjFanin0(pObj)->fMarkA | Aig_ObjFanin1(pObj)->fMarkA;
Saig_ManForEachLi( p->pAig, pObj, i )
pObj->fMarkA |= Aig_ObjFanin0(pObj)->fMarkA;
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
pObjLo->fMarkA |= pObjLi->fMarkA;
}
/**Function*************************************************************
Synopsis [Retrives value of the PI in the original AIG.] Synopsis [Retrives value of the PI in the original AIG.]
Description [] Description []
...@@ -89,12 +42,22 @@ void Ssw_ManSweepMarkRefinement( Ssw_Man_t * p ) ...@@ -89,12 +42,22 @@ void Ssw_ManSweepMarkRefinement( Ssw_Man_t * p )
***********************************************************************/ ***********************************************************************/
int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f ) int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
{ {
int fUseNoBoundary = 0;
Aig_Obj_t * pObjFraig; Aig_Obj_t * pObjFraig;
int nVarNum, Value; int Value;
// assert( Aig_ObjIsPi(pObj) ); // assert( Aig_ObjIsPi(pObj) );
pObjFraig = Ssw_ObjFrame( p, pObj, f ); pObjFraig = Ssw_ObjFrame( p, pObj, f );
nVarNum = Ssw_ObjSatNum( p, Aig_Regular(pObjFraig) ); if ( fUseNoBoundary )
Value = (!nVarNum)? 0 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pSat, nVarNum )); {
Value = Ssw_CnfGetNodeValue( p->pMSat, Aig_Regular(pObjFraig) );
Value ^= Aig_IsComplement(pObjFraig);
}
else
{
int nVarNum = Ssw_ObjSatNum( p->pMSat, Aig_Regular(pObjFraig) );
Value = (!nVarNum)? 0 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pMSat->pSat, nVarNum ));
}
// Value = (Aig_IsComplement(pObjFraig) ^ ((!nVarNum)? 0 : sat_solver_var_value( p->pSat, nVarNum ))); // Value = (Aig_IsComplement(pObjFraig) ^ ((!nVarNum)? 0 : sat_solver_var_value( p->pSat, nVarNum )));
// Value = (!nVarNum)? Aig_ManRandom(0) & 1 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pSat, nVarNum )); // Value = (!nVarNum)? Aig_ManRandom(0) & 1 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pSat, nVarNum ));
if ( p->pPars->fPolarFlip ) if ( p->pPars->fPolarFlip )
...@@ -181,15 +144,8 @@ int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc ) ...@@ -181,15 +144,8 @@ int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc )
// 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) )
return 0; return 0;
// count the number of skipped calls
if ( !pObj->fMarkA && !pObjRepr->fMarkA )
p->nRefSkip++;
else
p->nRefUse++;
// call equivalence checking // call equivalence checking
if ( p->pPars->fSkipCheck && !fBmc && !pObj->fMarkA && !pObjRepr->fMarkA ) if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) )
RetValue = 1;
else if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) )
RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) ); RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
else else
RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjFraig), Aig_Regular(pObjReprFraig) ); RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjFraig), Aig_Regular(pObjReprFraig) );
...@@ -204,18 +160,13 @@ int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc ) ...@@ -204,18 +160,13 @@ int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc )
Ssw_ClassesRemoveNode( p->ppClasses, pObj ); Ssw_ClassesRemoveNode( p->ppClasses, pObj );
return 1; return 1;
} }
// check if skipping calls works correctly
if ( p->pPars->fSkipCheck && !fBmc && !pObj->fMarkA && !pObjRepr->fMarkA )
{
assert( 0 );
printf( "\nSsw_ManSweepNode(): Error!\n" );
}
// disproved the equivalence // disproved the equivalence
Ssw_SmlSavePatternAig( p, f ); Ssw_SmlSavePatternAig( p, f );
} }
if ( !fBmc && p->pPars->fUniqueness && p->pPars->nFramesK > 1 && if ( !fBmc && p->pPars->fUniqueness && p->pPars->nFramesK > 1 &&
Ssw_ManUniqueOne( p, pObjRepr, pObj ) && p->iOutputLit == -1 ) Ssw_ManUniqueOne( p, pObjRepr, pObj ) && p->iOutputLit == -1 )
{ {
/*
if ( Ssw_ManUniqueAddConstraint( p, p->vCommon, 0, 1 ) ) if ( Ssw_ManUniqueAddConstraint( p, p->vCommon, 0, 1 ) )
{ {
int RetValue; int RetValue;
...@@ -224,12 +175,39 @@ int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc ) ...@@ -224,12 +175,39 @@ int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc )
p->iOutputLit = -1; p->iOutputLit = -1;
return RetValue; return RetValue;
} }
*/
if ( Ssw_ManUniqueAddConstraint( p, p->vCommon, 0, 1 ) )
{
int RetValue2 = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
p->iOutputLit = -1;
p->nUniques++;
p->nUniquesAdded++;
if ( RetValue2 == 0 )
{
int x;
// printf( "Second time:\n" );
x = Ssw_ManUniqueOne( p, pObjRepr, pObj );
Ssw_SmlSavePatternAig( p, f );
Ssw_ManResimulateWord( p, pObj, pObjRepr, f );
if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
printf( "Ssw_ManSweepNode(): Refinement did not happen!!!.\n" );
return 1;
}
else
p->nUniquesUseful++;
// printf( "Counter-example prevented!!!\n" );
return 0;
}
} }
if ( p->pPars->nConstrs == 0 ) if ( p->pPars->nConstrs == 0 )
Ssw_ManResimulateWord( p, pObj, pObjRepr, f ); Ssw_ManResimulateWord( p, pObj, pObjRepr, f );
else else
Ssw_ManResimulateBit( p, pObj, pObjRepr ); Ssw_ManResimulateBit( p, pObj, pObjRepr );
assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr ); assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr );
if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
{
printf( "Ssw_ManSweepNode(): Failed to refine representative.\n" );
}
return 1; return 1;
} }
...@@ -260,7 +238,7 @@ clk = clock(); ...@@ -260,7 +238,7 @@ clk = clock();
p->fRefined = 0; p->fRefined = 0;
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK ); pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
Ssw_ManStartSolver( p ); // Ssw_ManStartSolver( p );
for ( f = 0; f < p->pPars->nFramesK; f++ ) for ( f = 0; f < p->pPars->nFramesK; f++ )
{ {
// map constants and PIs // map constants and PIs
...@@ -285,7 +263,7 @@ clk = clock(); ...@@ -285,7 +263,7 @@ clk = clock();
{ {
pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f); pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f);
Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew ); Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) ); Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pObjNew) );//
} }
} }
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
...@@ -308,19 +286,63 @@ p->timeBmc += clock() - clk; ...@@ -308,19 +286,63 @@ p->timeBmc += clock() - clk;
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Ssw_ManSweep( Ssw_Man_t * p ) void Ssw_CheckConstaints( Ssw_Man_t * p )
{ {
Aig_Obj_t * pObj, * pObj2;
int nConstrPairs, i;
int Counter = 0;
nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig);
assert( (nConstrPairs & 1) == 0 );
for ( i = 0; i < nConstrPairs; i += 2 )
{
pObj = Aig_ManPo( p->pFrames, i );
pObj2 = Aig_ManPo( p->pFrames, i+1 );
if ( Ssw_NodesAreEquiv( p, Aig_ObjFanin0(pObj), Aig_ObjFanin0(pObj2) ) != 1 )
{
Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj), Aig_ObjChild0(pObj2) );
Counter++;
}
}
printf( "Total constraints = %d. Added constraints = %d.\n", nConstrPairs/2, Counter );
}
/**Function*************************************************************
Synopsis [Performs fraiging for the internal nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManSweep( Ssw_Man_t * p )
{
Bar_Progress_t * pProgress = NULL; Bar_Progress_t * pProgress = NULL;
Aig_Obj_t * pObj, * pObj2, * pObjNew; Aig_Obj_t * pObj, * pObj2, * pObjNew;
int nConstrPairs, clk, i, f; int nConstrPairs, clk, i, f;
int v; // int v;
// perform speculative reduction // perform speculative reduction
clk = clock(); clk = clock();
// create timeframes // create timeframes
p->pFrames = Ssw_FramesWithClasses( p ); p->pFrames = Ssw_FramesWithClasses( p );
// add constraints // add constraints
Ssw_ManStartSolver( p ); // p->pMSat = Ssw_SatStart( 0 );
// Ssw_ManStartSolver( p );
/*
{
int clk2 = clock();
Ssw_CheckConstaints( p );
PRT( "Time", clock() - clk2 );
}
Ssw_ManCleanup( p );
p->pFrames = Ssw_FramesWithClasses( p );
p->pMSat = Ssw_SatStart( 0 );
// Ssw_ManStartSolver( p );
*/
nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig); nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig);
assert( (nConstrPairs & 1) == 0 ); assert( (nConstrPairs & 1) == 0 );
for ( i = 0; i < nConstrPairs; i += 2 ) for ( i = 0; i < nConstrPairs; i += 2 )
...@@ -333,17 +355,11 @@ clk = clock(); ...@@ -333,17 +355,11 @@ clk = clock();
for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ ) for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ )
{ {
pObj = Aig_ManPo( p->pFrames, nConstrPairs + i ); pObj = Aig_ManPo( p->pFrames, nConstrPairs + i );
Ssw_CnfNodeAddToSolver( p, Aig_ObjFanin0(pObj) ); Ssw_CnfNodeAddToSolver( p->pMSat, Aig_ObjFanin0(pObj) );//
} }
sat_solver_simplify( p->pSat ); sat_solver_simplify( p->pMSat->pSat );
p->timeReduce += clock() - clk; p->timeReduce += clock() - clk;
// mark nodes that do not have to be refined
clk = clock();
if ( p->pPars->fSkipCheck )
Ssw_ManSweepMarkRefinement( p );
p->timeMarkCones += clock() - clk;
//Ssw_ManUnique( p ); //Ssw_ManUnique( p );
// map constants and PIs of the last frame // map constants and PIs of the last frame
...@@ -354,17 +370,26 @@ p->timeMarkCones += clock() - clk; ...@@ -354,17 +370,26 @@ p->timeMarkCones += clock() - clk;
// make sure LOs are assigned // make sure LOs are assigned
Saig_ManForEachLo( p->pAig, pObj, i ) Saig_ManForEachLo( p->pAig, pObj, i )
assert( Ssw_ObjFrame( p, pObj, f ) != NULL ); assert( Ssw_ObjFrame( p, pObj, f ) != NULL );
/*
// mark the PI/LO of the last frame
Aig_ManForEachPi( p->pAig, pObj, i )
{
pObjNew = Ssw_ObjFrame( p, pObj, f );
Aig_Regular(pObjNew)->fMarkA = 1;
}
*/
//// ////
/*
// bring up the previous frames // bring up the previous frames
if ( p->pPars->fUniqueness ) if ( p->pPars->fUniqueness )
for ( v = 0; v < f; v++ ) for ( v = 0; v < f; v++ )
Saig_ManForEachLo( p->pAig, pObj, i ) Saig_ManForEachLo( p->pAig, pObj, i )
Ssw_CnfNodeAddToSolver( p, Aig_Regular(Ssw_ObjFrame(p, pObj, v)) ); Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(Ssw_ObjFrame(p, pObj, v)) );
*/
//// ////
// sweep internal nodes // sweep internal nodes
p->fRefined = 0; p->fRefined = 0;
p->nSatFailsReal = 0; p->nSatFailsReal = 0;
p->nRefUse = p->nRefSkip = 0;
p->nUniques = 0; p->nUniques = 0;
Ssw_ClassesClearRefined( p->ppClasses ); Ssw_ClassesClearRefined( p->ppClasses );
if ( p->pPars->fVerbose ) if ( p->pPars->fVerbose )
......
...@@ -30,83 +30,39 @@ ...@@ -30,83 +30,39 @@
/**Function************************************************************* /**Function*************************************************************
Synopsis [Returns the result of merging the two vectors.] Synopsis [Performs computation of signal correspondence with constraints.]
Description [Assumes that the vectors are sorted in the increasing order.] Description []
SideEffects [] SideEffects []
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
static inline void Vec_PtrTwoMerge( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr ) void Ssw_UniqueRegisterPairInfo( Ssw_Man_t * p )
{ {
Aig_Obj_t ** pBeg = (Aig_Obj_t **)vArr->pArray; Aig_Obj_t * pObjLo, * pObj0, * pObj1;
Aig_Obj_t ** pBeg1 = (Aig_Obj_t **)vArr1->pArray; int i;
Aig_Obj_t ** pBeg2 = (Aig_Obj_t **)vArr2->pArray; if ( p->vDiffPairs == NULL )
Aig_Obj_t ** pEnd1 = (Aig_Obj_t **)vArr1->pArray + vArr1->nSize; p->vDiffPairs = Vec_IntAlloc( Saig_ManRegNum(p->pAig) );
Aig_Obj_t ** pEnd2 = (Aig_Obj_t **)vArr2->pArray + vArr2->nSize; Vec_IntClear( p->vDiffPairs );
Vec_PtrGrow( vArr, Vec_PtrSize(vArr1) + Vec_PtrSize(vArr2) ); Saig_ManForEachLo( p->pAig, pObjLo, i )
pBeg = (Aig_Obj_t **)vArr->pArray;
while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
{ {
if ( (*pBeg1)->Id == (*pBeg2)->Id ) pObj0 = Ssw_ObjFrame( p, pObjLo, 0 );
*pBeg++ = *pBeg1++, pBeg2++; pObj1 = Ssw_ObjFrame( p, pObjLo, 1 );
else if ( (*pBeg1)->Id < (*pBeg2)->Id ) if ( pObj0 == pObj1 )
*pBeg++ = *pBeg1++; Vec_IntPush( p->vDiffPairs, 0 );
else if ( pObj0 == Aig_Not(pObj1) )
Vec_IntPush( p->vDiffPairs, 1 );
else else
*pBeg++ = *pBeg2++; {
// assume that if the nodes are structurally different
// they can also be functionally different
Vec_IntPush( p->vDiffPairs, 1 );
}
} }
while ( pBeg1 < pEnd1 )
*pBeg++ = *pBeg1++;
while ( pBeg2 < pEnd2 )
*pBeg++ = *pBeg2++;
vArr->nSize = pBeg - (Aig_Obj_t **)vArr->pArray;
assert( vArr->nSize <= vArr->nCap );
assert( vArr->nSize >= vArr1->nSize );
assert( vArr->nSize >= vArr2->nSize );
} }
/**Function*************************************************************
Synopsis [Returns the result of merging the two vectors.]
Description [Assumes that the vectors are sorted in the increasing order.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_PtrTwoCommon( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr )
{
Aig_Obj_t ** pBeg = (Aig_Obj_t **)vArr->pArray;
Aig_Obj_t ** pBeg1 = (Aig_Obj_t **)vArr1->pArray;
Aig_Obj_t ** pBeg2 = (Aig_Obj_t **)vArr2->pArray;
Aig_Obj_t ** pEnd1 = (Aig_Obj_t **)vArr1->pArray + vArr1->nSize;
Aig_Obj_t ** pEnd2 = (Aig_Obj_t **)vArr2->pArray + vArr2->nSize;
Vec_PtrGrow( vArr, AIG_MAX( Vec_PtrSize(vArr1), Vec_PtrSize(vArr2) ) );
pBeg = (Aig_Obj_t **)vArr->pArray;
while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
{
if ( (*pBeg1)->Id == (*pBeg2)->Id )
*pBeg++ = *pBeg1++, pBeg2++;
else if ( (*pBeg1)->Id < (*pBeg2)->Id )
// *pBeg++ = *pBeg1++;
pBeg1++;
else
// *pBeg++ = *pBeg2++;
pBeg2++;
}
// while ( pBeg1 < pEnd1 )
// *pBeg++ = *pBeg1++;
// while ( pBeg2 < pEnd2 )
// *pBeg++ = *pBeg2++;
vArr->nSize = pBeg - (Aig_Obj_t **)vArr->pArray;
assert( vArr->nSize <= vArr->nCap );
assert( vArr->nSize <= vArr1->nSize );
assert( vArr->nSize <= vArr2->nSize );
}
/**Function************************************************************* /**Function*************************************************************
...@@ -123,56 +79,32 @@ int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj ) ...@@ -123,56 +79,32 @@ int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj )
{ {
int fVerbose = 0; int fVerbose = 0;
Aig_Obj_t * ppObjs[2], * pTemp; Aig_Obj_t * ppObjs[2], * pTemp;
Vec_Ptr_t * vSupp, * vSupp2; int i, k, Value0, Value1, RetValue, fFeasible;
int i, k, Value0, Value1, RetValue;
assert( p->pPars->nFramesK > 1 );
vSupp = Vec_PtrAlloc( 100 ); assert( p->pPars->nFramesK > 1 );
vSupp2 = Vec_PtrAlloc( 100 ); assert( p->vDiffPairs && Vec_IntSize(p->vDiffPairs) == Saig_ManRegNum(p->pAig) );
Vec_PtrClear( p->vCommon );
// compute the first support in terms of LOs // compute the first support in terms of LOs
ppObjs[0] = pRepr; ppObjs[0] = pRepr;
ppObjs[1] = pObj; ppObjs[1] = pObj;
Aig_SupportNodes( p->pAig, ppObjs, 2, vSupp ); Aig_SupportNodes( p->pAig, ppObjs, 2, p->vCommon );
// modify support to be in terms of LIs // keep only LOs
RetValue = Vec_PtrSize( p->vCommon );
fFeasible = 0;
k = 0; k = 0;
Vec_PtrForEachEntry( vSupp, pTemp, i ) Vec_PtrForEachEntry( p->vCommon, pTemp, i )
if ( Saig_ObjIsLo(p->pAig, pTemp) ) if ( Saig_ObjIsLo(p->pAig, pTemp) )
Vec_PtrWriteEntry( vSupp, k++, Saig_ObjLoToLi(p->pAig, pTemp) ); {
Vec_PtrShrink( vSupp, k ); Vec_PtrWriteEntry( p->vCommon, k++, pTemp );
// compute the support of support if ( Vec_IntEntry(p->vDiffPairs, Aig_ObjPioNum(pTemp) - Saig_ManPiNum(p->pAig)) )
Aig_SupportNodes( p->pAig, (Aig_Obj_t **)Vec_PtrArray(vSupp), Vec_PtrSize(vSupp), vSupp2 ); fFeasible = 1;
// return support to LO }
Vec_PtrForEachEntry( vSupp, pTemp, i ) Vec_PtrShrink( p->vCommon, k );
Vec_PtrWriteEntry( vSupp, i, Saig_ObjLiToLo(p->pAig, pTemp) );
// find the number of common vars
Vec_PtrSort( vSupp, Aig_ObjCompareIdIncrease );
Vec_PtrSort( vSupp2, Aig_ObjCompareIdIncrease );
Vec_PtrTwoCommon( vSupp, vSupp2, p->vCommon );
/*
{
Vec_Ptr_t * vNew = Vec_PtrDup(vSupp);
Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease );
if ( Vec_PtrSize(vNew) != Vec_PtrSize(vSupp) )
printf( "Not unique!\n" );
}
{
Vec_Ptr_t * vNew = Vec_PtrDup(vSupp2);
Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease );
if ( Vec_PtrSize(vNew) != Vec_PtrSize(vSupp2) )
printf( "Not unique!\n" );
}
{
Vec_Ptr_t * vNew = Vec_PtrDup(p->vCommon);
Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease );
if ( Vec_PtrSize(vNew) != Vec_PtrSize(p->vCommon) )
printf( "Not unique!\n" );
}
*/
if ( fVerbose ) if ( fVerbose )
printf( "Node = %5d : One = %3d. Two = %3d. Common = %3d. ", printf( "Node = %5d : Supp = %3d. Regs = %3d. Feasible = %s. ",
Aig_ObjId(pObj), Vec_PtrSize(vSupp), Vec_PtrSize(vSupp2), Vec_PtrSize(p->vCommon) ); Aig_ObjId(pObj), RetValue, Vec_PtrSize(p->vCommon),
fFeasible? "yes": "no " );
// check the current values // check the current values
RetValue = 1; RetValue = 1;
...@@ -185,14 +117,10 @@ int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj ) ...@@ -185,14 +117,10 @@ int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj )
if ( fVerbose ) if ( fVerbose )
printf( "%d", Value0 ^ Value1 ); printf( "%d", Value0 ^ Value1 );
} }
if ( Vec_PtrSize(p->vCommon) == 0 )
RetValue = 0;
if ( fVerbose ) if ( fVerbose )
printf( "\n" ); printf( "\n" );
Vec_PtrFree( vSupp ); return RetValue && fFeasible;
Vec_PtrFree( vSupp2 );
return RetValue;
} }
/**Function************************************************************* /**Function*************************************************************
...@@ -227,11 +155,10 @@ int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int ...@@ -227,11 +155,10 @@ int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int
// printf( "Skipped\n" ); // printf( "Skipped\n" );
return 0; return 0;
} }
p->nUniques++;
// create CNF // create CNF
Ssw_CnfNodeAddToSolver( p, Aig_Regular(pTotal) ); Ssw_CnfNodeAddToSolver( p->pMSat, Aig_Regular(pTotal) );
// add output constraint // add output constraint
pLits[0] = toLitCond( Ssw_ObjSatNum(p,Aig_Regular(pTotal)), Aig_IsComplement(pTotal) ); pLits[0] = toLitCond( Ssw_ObjSatNum(p->pMSat,Aig_Regular(pTotal)), Aig_IsComplement(pTotal) );
/* /*
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 ); RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 );
assert( RetValue ); assert( RetValue );
......
SRC += src/aig/ssw/sswAig.c \
src/aig/ssw/sswBmc.c \
src/aig/ssw/sswClass.c \
src/aig/ssw/sswCnf.c \
src/aig/ssw/sswCore.c \
src/aig/ssw/sswLcorr.c \
src/aig/ssw/sswMan.c \
src/aig/ssw/sswPart.c \
src/aig/ssw/sswPairs.c \
src/aig/ssw/sswSat.c \
src/aig/ssw/sswSim.c \
src/aig/ssw/sswSimSat.c \
src/aig/ssw/sswSweep.c \
src/aig/ssw/sswUnique.c
/**CFile****************************************************************
FileName [ssw.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: ssw.h,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __SSW_H__
#define __SSW_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
// choicing parameters
typedef struct Ssw_Pars_t_ Ssw_Pars_t;
struct Ssw_Pars_t_
{
int nPartSize; // size of the partition
int nOverSize; // size of the overlap between partitions
int nFramesK; // the induction depth
int nFramesAddSim; // the number of additional frames to simulate
int nConstrs; // treat the last nConstrs POs as seq constraints
int nMaxLevs; // the max number of levels of nodes to consider
int nBTLimit; // conflict limit at a node
int nMinDomSize; // min clock domain considered for optimization
int fPolarFlip; // uses polarity adjustment
int fSkipCheck; // do not run equivalence check for unaffected cones
int fLatchCorr; // perform register correspondence
int fSemiFormal; // enable semiformal filtering
int fUniqueness; // enable uniqueness constraints
int fVerbose; // verbose stats
// optimized latch correspondence
int fLatchCorrOpt; // perform register correspondence (optimized)
int nSatVarMax; // max number of SAT vars before recycling SAT solver (optimized latch corr only)
int nRecycleCalls; // calls to perform before recycling SAT solver (optimized latch corr only)
// internal parameters
int nIters; // the number of iterations performed
};
// sequential counter-example
typedef struct Ssw_Cex_t_ Ssw_Cex_t;
struct Ssw_Cex_t_
{
int iPo; // the zero-based number of PO, for which verification failed
int iFrame; // the zero-based number of the time-frame, for which verificaiton failed
int nRegs; // the number of registers in the miter
int nPis; // the number of primary inputs in the miter
int nBits; // the number of words of bit data used
unsigned pData[0]; // the cex bit data (the number of bits: nRegs + (iFrame+1) * nPis)
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== sswAbs.c ==========================================================*/
extern Aig_Man_t * Saig_ManProofAbstraction( Aig_Man_t * p, int nFrames, int nConfMax, int fVerbose );
/*=== sswCore.c ==========================================================*/
extern void Ssw_ManSetDefaultParams( Ssw_Pars_t * p );
extern void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p );
extern Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
extern Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
/*=== sswLoc.c ==========================================================*/
extern int Saig_ManLocalization( Aig_Man_t * p, int nFramesMax, int nConfMax, int fVerbose );
/*=== sswPart.c ==========================================================*/
extern Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
/*=== sswPairs.c ===================================================*/
extern int Ssw_SecWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars );
extern int Ssw_SecGeneral( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Ssw_Pars_t * pPars );
extern int Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars );
/*=== sswSim.c ===================================================*/
extern Ssw_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames );
extern void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex );
extern int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p );
extern int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p );
extern Ssw_Cex_t * Ssw_SmlDupCounterExample( Ssw_Cex_t * p, int nRegsNew );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswAig.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [AIG manipulation.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswAig.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs speculative reduction for one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Ssw_FramesConstrainNode( Ssw_Man_t * p, Aig_Man_t * pFrames, Aig_Man_t * pAig, Aig_Obj_t * pObj, int iFrame, int fTwoPos )
{
Aig_Obj_t * pObjNew, * pObjNew2, * pObjRepr, * pObjReprNew, * pMiter;
// skip nodes without representative
pObjRepr = Aig_ObjRepr(pAig, pObj);
if ( pObjRepr == NULL )
return;
p->nConstrTotal++;
assert( pObjRepr->Id < pObj->Id );
// get the new node
pObjNew = Ssw_ObjFrame( p, pObj, iFrame );
// get the new node of the representative
pObjReprNew = Ssw_ObjFrame( p, pObjRepr, iFrame );
// if this is the same node, no need to add constraints
if ( pObj->fPhase == pObjRepr->fPhase )
{
assert( pObjNew != Aig_Not(pObjReprNew) );
if ( pObjNew == pObjReprNew )
return;
}
else
{
assert( pObjNew != pObjReprNew );
if ( pObjNew == Aig_Not(pObjReprNew) )
return;
}
p->nConstrReduced++;
// these are different nodes - perform speculative reduction
pObjNew2 = Aig_NotCond( pObjReprNew, pObj->fPhase ^ pObjRepr->fPhase );
// set the new node
Ssw_ObjSetFrame( p, pObj, iFrame, pObjNew2 );
// add the constraint
if ( fTwoPos )
{
Aig_ObjCreatePo( pFrames, pObjNew2 );
Aig_ObjCreatePo( pFrames, pObjNew );
}
else
{
pMiter = Aig_Exor( pFrames, pObjNew, pObjNew2 );
Aig_ObjCreatePo( pFrames, Aig_NotCond(pMiter, Aig_ObjPhaseReal(pMiter)) );
}
}
/**Function*************************************************************
Synopsis [Prepares the inductive case with speculative reduction.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p )
{
Aig_Man_t * pFrames;
Aig_Obj_t * pObj, * pObjLi, * pObjLo, * pObjNew;
int i, f;
assert( p->pFrames == NULL );
assert( Aig_ManRegNum(p->pAig) > 0 );
assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
p->nConstrTotal = p->nConstrReduced = 0;
// start the fraig package
pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames );
// create latches for the first frame
Saig_ManForEachLo( p->pAig, pObj, i )
Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) );
// add timeframes
for ( f = 0; f < p->pPars->nFramesK; f++ )
{
// map constants and PIs
Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(pFrames) );
Saig_ManForEachPi( p->pAig, pObj, i )
Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(pFrames) );
// set the constraints on the latch outputs
Saig_ManForEachLo( p->pAig, pObj, i )
Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, f, 1 );
// add internal nodes of this frame
Aig_ManForEachNode( p->pAig, pObj, i )
{
pObjNew = Aig_And( pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
Ssw_ObjSetFrame( p, pObj, f, pObjNew );
Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, f, 1 );
}
// transfer latch input to the latch outputs
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
Ssw_ObjSetFrame( p, pObjLo, f+1, Ssw_ObjChild0Fra(p, pObjLi,f) );
}
// add the POs for the latch outputs of the last frame
// Saig_ManForEachLo( p->pAig, pObj, i )
// Aig_ObjCreatePo( pFrames, Ssw_ObjFrame( p, pObj, p->pPars->nFramesK ) );
for ( f = 0; f <= p->pPars->nFramesK; f++ )
Saig_ManForEachLo( p->pAig, pObj, i )
Aig_ObjCreatePo( pFrames, Ssw_ObjFrame( p, pObj, f ) );
// remove dangling nodes
Aig_ManCleanup( pFrames );
// make sure the satisfying assignment is node assigned
assert( pFrames->pData == NULL );
//Aig_ManShow( pFrames, 0, NULL );
return pFrames;
}
/**Function*************************************************************
Synopsis [Prepares the inductive case with speculative reduction.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p )
{
Aig_Man_t * pFrames;
Aig_Obj_t * pObj, * pObjNew;
int i;
assert( p->pFrames == NULL );
assert( Aig_ManRegNum(p->pAig) > 0 );
assert( Aig_ManRegNum(p->pAig) < Aig_ManPiNum(p->pAig) );
p->nConstrTotal = p->nConstrReduced = 0;
// start the fraig package
pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->nFrames );
// map constants and PIs
Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(pFrames) );
Saig_ManForEachPi( p->pAig, pObj, i )
Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) );
// create latches for the first frame
Saig_ManForEachLo( p->pAig, pObj, i )
Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(pFrames) );
// set the constraints on the latch outputs
Saig_ManForEachLo( p->pAig, pObj, i )
Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, 0, 0 );
// add internal nodes of this frame
Aig_ManForEachNode( p->pAig, pObj, i )
{
pObjNew = Aig_And( pFrames, Ssw_ObjChild0Fra(p, pObj, 0), Ssw_ObjChild1Fra(p, pObj, 0) );
Ssw_ObjSetFrame( p, pObj, 0, pObjNew );
Ssw_FramesConstrainNode( p, pFrames, p->pAig, pObj, 0, 0 );
}
// add the POs for the latch outputs of the last frame
Saig_ManForEachLi( p->pAig, pObj, i )
Aig_ObjCreatePo( pFrames, Ssw_ObjChild0Fra(p, pObj,0) );
// remove dangling nodes
Aig_ManCleanup( pFrames );
Aig_ManSetRegNum( pFrames, Aig_ManRegNum(p->pAig) );
printf( "SpecRed: Total constraints = %d. Reduced constraints = %d.\n",
p->nConstrTotal, p->nConstrReduced );
return pFrames;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswClass.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [Representation of candidate equivalence classes.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswClass.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
/*
The candidate equivalence classes are stored as a vector of pointers
to the array of pointers to the nodes in each class.
The first node of the class is its representative node.
The representative has the smallest topological order among the class nodes.
The nodes inside each class are ordered according to their topological order.
The classes are ordered according to the topo order of their representatives.
*/
// internal representation of candidate equivalence classes
struct Ssw_Cla_t_
{
// class information
Aig_Man_t * pAig; // original AIG manager
Aig_Obj_t *** pId2Class; // non-const classes by ID of repr node
int * pClassSizes; // sizes of each equivalence class
// statistics
int nClasses; // the total number of non-const classes
int nCands1; // the total number of const candidates
int nLits; // the number of literals in all classes
// memory
Aig_Obj_t ** pMemClasses; // memory allocated for equivalence classes
Aig_Obj_t ** pMemClassesFree; // memory allocated for equivalence classes to be used
// temporary data
Vec_Ptr_t * vClassOld; // old equivalence class after splitting
Vec_Ptr_t * vClassNew; // new equivalence class(es) after splitting
Vec_Ptr_t * vRefined; // the nodes refined since the last iteration
// procedures used for class refinement
void * pManData;
unsigned (*pFuncNodeHash) (void *,Aig_Obj_t *); // returns hash key of the node
int (*pFuncNodeIsConst) (void *,Aig_Obj_t *); // returns 1 if the node is a constant
int (*pFuncNodesAreEqual) (void *,Aig_Obj_t *, Aig_Obj_t *); // returns 1 if nodes are equal up to a complement
};
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
static inline Aig_Obj_t * Ssw_ObjNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj ) { return ppNexts[pObj->Id]; }
static inline void Ssw_ObjSetNext( Aig_Obj_t ** ppNexts, Aig_Obj_t * pObj, Aig_Obj_t * pNext ) { ppNexts[pObj->Id] = pNext; }
// iterator through the equivalence classes
#define Ssw_ManForEachClass( p, ppClass, i ) \
for ( i = 0; i < Aig_ManObjNumMax(p->pAig); i++ ) \
if ( ((ppClass) = p->pId2Class[i]) == NULL ) {} else
// iterator through the nodes in one class
#define Ssw_ClassForEachNode( p, pRepr, pNode, i ) \
for ( i = 0; i < p->pClassSizes[pRepr->Id]; i++ ) \
if ( ((pNode) = p->pId2Class[pRepr->Id][i]) == NULL ) {} else
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates one equivalence class.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Ssw_ObjAddClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Aig_Obj_t ** pClass, int nSize )
{
assert( p->pId2Class[pRepr->Id] == NULL );
assert( pClass[0] == pRepr );
p->pId2Class[pRepr->Id] = pClass;
assert( p->pClassSizes[pRepr->Id] == 0 );
assert( nSize > 1 );
p->pClassSizes[pRepr->Id] = nSize;
p->nClasses++;
p->nLits += nSize - 1;
}
/**Function*************************************************************
Synopsis [Removes one equivalence class.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline Aig_Obj_t ** Ssw_ObjRemoveClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr )
{
Aig_Obj_t ** pClass = p->pId2Class[pRepr->Id];
int nSize;
assert( pClass != NULL );
p->pId2Class[pRepr->Id] = NULL;
nSize = p->pClassSizes[pRepr->Id];
assert( nSize > 1 );
p->nClasses--;
p->nLits -= nSize - 1;
p->pClassSizes[pRepr->Id] = 0;
return pClass;
}
/**Function*************************************************************
Synopsis [Starts representation of equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Cla_t * Ssw_ClassesStart( Aig_Man_t * pAig )
{
Ssw_Cla_t * p;
p = ALLOC( Ssw_Cla_t, 1 );
memset( p, 0, sizeof(Ssw_Cla_t) );
p->pAig = pAig;
p->pId2Class = CALLOC( Aig_Obj_t **, Aig_ManObjNumMax(pAig) );
p->pClassSizes = CALLOC( int, Aig_ManObjNumMax(pAig) );
p->vClassOld = Vec_PtrAlloc( 100 );
p->vClassNew = Vec_PtrAlloc( 100 );
p->vRefined = Vec_PtrAlloc( 1000 );
assert( pAig->pReprs == NULL );
Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
return p;
}
/**Function*************************************************************
Synopsis [Starts representation of equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ClassesSetData( Ssw_Cla_t * p, void * pManData,
unsigned (*pFuncNodeHash)(void *,Aig_Obj_t *), // returns hash key of the node
int (*pFuncNodeIsConst)(void *,Aig_Obj_t *), // returns 1 if the node is a constant
int (*pFuncNodesAreEqual)(void *,Aig_Obj_t *, Aig_Obj_t *) ) // returns 1 if nodes are equal up to a complement
{
p->pManData = pManData;
p->pFuncNodeHash = pFuncNodeHash;
p->pFuncNodeIsConst = pFuncNodeIsConst;
p->pFuncNodesAreEqual = pFuncNodesAreEqual;
}
/**Function*************************************************************
Synopsis [Stop representation of equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ClassesStop( Ssw_Cla_t * p )
{
if ( p->vClassNew ) Vec_PtrFree( p->vClassNew );
if ( p->vClassOld ) Vec_PtrFree( p->vClassOld );
Vec_PtrFree( p->vRefined );
FREE( p->pId2Class );
FREE( p->pClassSizes );
FREE( p->pMemClasses );
free( p );
}
/**Function*************************************************************
Synopsis [Stop representation of equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ssw_ClassesReadAig( Ssw_Cla_t * p )
{
return p->pAig;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Ssw_ClassesGetRefined( Ssw_Cla_t * p )
{
return p->vRefined;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ClassesClearRefined( Ssw_Cla_t * p )
{
Vec_PtrClear( p->vRefined );
}
/**Function*************************************************************
Synopsis [Stop representation of equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ClassesCand1Num( Ssw_Cla_t * p )
{
return p->nCands1;
}
/**Function*************************************************************
Synopsis [Stop representation of equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ClassesClassNum( Ssw_Cla_t * p )
{
return p->nClasses;
}
/**Function*************************************************************
Synopsis [Stop representation of equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ClassesLitNum( Ssw_Cla_t * p )
{
return p->nLits;
}
/**Function*************************************************************
Synopsis [Stop representation of equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Obj_t ** Ssw_ClassesReadClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int * pnSize )
{
if ( p->pId2Class[pRepr->Id] == NULL )
return NULL;
assert( p->pId2Class[pRepr->Id] != NULL );
assert( p->pClassSizes[pRepr->Id] > 1 );
*pnSize = p->pClassSizes[pRepr->Id];
return p->pId2Class[pRepr->Id];
}
/**Function*************************************************************
Synopsis [Stop representation of equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ClassesCollectClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Vec_Ptr_t * vClass )
{
int i;
Vec_PtrClear( vClass );
if ( p->pId2Class[pRepr->Id] == NULL )
return;
assert( p->pClassSizes[pRepr->Id] > 1 );
for ( i = 1; i < p->pClassSizes[pRepr->Id]; i++ )
Vec_PtrPush( vClass, p->pId2Class[pRepr->Id][i] );
}
/**Function*************************************************************
Synopsis [Checks candidate equivalence classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ClassesCheck( Ssw_Cla_t * p )
{
Aig_Obj_t * pObj, * pPrev, ** ppClass;
int i, k, nLits, nClasses, nCands1;
nClasses = nLits = 0;
Ssw_ManForEachClass( p, ppClass, k )
{
pPrev = NULL;
assert( p->pClassSizes[ppClass[0]->Id] >= 2 );
Ssw_ClassForEachNode( p, ppClass[0], pObj, i )
{
if ( i == 0 )
assert( Aig_ObjRepr(p->pAig, pObj) == NULL );
else
{
assert( Aig_ObjRepr(p->pAig, pObj) == ppClass[0] );
assert( pPrev->Id < pObj->Id );
nLits++;
}
pPrev = pObj;
}
nClasses++;
}
nCands1 = 0;
Aig_ManForEachObj( p->pAig, pObj, i )
nCands1 += Ssw_ObjIsConst1Cand( p->pAig, pObj );
assert( p->nLits == nLits );
assert( p->nCands1 == nCands1 );
assert( p->nClasses == nClasses );
}
/**Function*************************************************************
Synopsis [Prints simulation classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ClassesPrintOne( Ssw_Cla_t * p, Aig_Obj_t * pRepr )
{
Aig_Obj_t * pObj;
int i;
printf( "{ " );
Ssw_ClassForEachNode( p, pRepr, pObj, i )
printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) );
printf( "}\n" );
}
/**Function*************************************************************
Synopsis [Prints simulation classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose )
{
Aig_Obj_t ** ppClass;
Aig_Obj_t * pObj;
int i;
printf( "Equivalence classes: Const1 = %5d. Class = %5d. Lit = %5d.\n",
p->nCands1, p->nClasses, p->nCands1+p->nLits );
if ( !fVeryVerbose )
return;
printf( "Constants { " );
Aig_ManForEachObj( p->pAig, pObj, i )
if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
printf( "%d(%d,%d) ", pObj->Id, pObj->Level, Aig_SupportSize(p->pAig,pObj) );
printf( "}\n" );
Ssw_ManForEachClass( p, ppClass, i )
{
printf( "%3d (%3d) : ", i, p->pClassSizes[i] );
Ssw_ClassesPrintOne( p, ppClass[0] );
}
printf( "\n" );
}
/**Function*************************************************************
Synopsis [Prints simulation classes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ClassesRemoveNode( Ssw_Cla_t * p, Aig_Obj_t * pObj )
{
Aig_Obj_t * pRepr, * pTemp;
assert( p->pClassSizes[pObj->Id] == 0 );
assert( p->pId2Class[pObj->Id] == NULL );
pRepr = Aig_ObjRepr( p->pAig, pObj );
assert( pRepr != NULL );
Vec_PtrPush( p->vRefined, pObj );
if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
{
assert( p->pClassSizes[pRepr->Id] == 0 );
assert( p->pId2Class[pRepr->Id] == NULL );
Aig_ObjSetRepr( p->pAig, pObj, NULL );
p->nCands1--;
return;
}
Vec_PtrPush( p->vRefined, pRepr );
Aig_ObjSetRepr( p->pAig, pObj, NULL );
assert( p->pId2Class[pRepr->Id][0] == pRepr );
assert( p->pClassSizes[pRepr->Id] >= 2 );
if ( p->pClassSizes[pRepr->Id] == 2 )
{
p->pId2Class[pRepr->Id] = NULL;
p->nClasses--;
p->pClassSizes[pRepr->Id] = 0;
p->nLits--;
}
else
{
int i, k = 0;
// remove the entry from the class
Ssw_ClassForEachNode( p, pRepr, pTemp, i )
if ( pTemp != pObj )
p->pId2Class[pRepr->Id][k++] = pTemp;
assert( k + 1 == p->pClassSizes[pRepr->Id] );
// reduce the class
p->pClassSizes[pRepr->Id]--;
p->nLits--;
}
}
/**Function*************************************************************
Synopsis [Creates initial simulation classes.]
Description [Assumes that simulation info is assigned.]
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs, int fVerbose )
{
Ssw_Cla_t * p;
Ssw_Sml_t * pSml;
Aig_Obj_t ** ppTable, ** ppNexts, ** ppClassNew;
Aig_Obj_t * pObj, * pTemp, * pRepr;
int i, k, nTableSize, nNodes, iEntry, nEntries, nEntries2;
int clk;
// start the classes
p = Ssw_ClassesStart( pAig );
// perform sequential simulation
clk = clock();
pSml = Ssw_SmlSimulateSeq( pAig, 0, 32, 4 );
if ( fVerbose )
{
PRT( "Simulation of 32 frames with 4 words", clock() - clk );
}
// set comparison procedures
clk = clock();
Ssw_ClassesSetData( p, pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord );
// allocate the hash table hashing simulation info into nodes
nTableSize = Aig_PrimeCudd( Aig_ManObjNumMax(p->pAig)/4 );
ppTable = CALLOC( Aig_Obj_t *, nTableSize );
ppNexts = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) );
// add all the nodes to the hash table
nEntries = 0;
Aig_ManForEachObj( p->pAig, pObj, i )
{
if ( fLatchCorr )
{
if ( !Saig_ObjIsLo(p->pAig, pObj) )
continue;
}
else
{
if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
continue;
// skip the node with more that the given number of levels
if ( nMaxLevs && (int)pObj->Level > nMaxLevs )
continue;
}
// check if the node belongs to the class of constant 1
if ( p->pFuncNodeIsConst( p->pManData, pObj ) )
{
Ssw_ObjSetConst1Cand( p->pAig, pObj );
p->nCands1++;
continue;
}
// hash the node by its simulation info
iEntry = p->pFuncNodeHash( p->pManData, pObj ) % nTableSize;
// add the node to the class
if ( ppTable[iEntry] == NULL )
ppTable[iEntry] = pObj;
else
{
// set the representative of this node
pRepr = ppTable[iEntry];
Aig_ObjSetRepr( p->pAig, pObj, pRepr );
// add node to the table
if ( Ssw_ObjNext( ppNexts, pRepr ) == NULL )
{ // this will be the second entry
p->pClassSizes[pRepr->Id]++;
nEntries++;
}
// add the entry to the list
Ssw_ObjSetNext( ppNexts, pObj, Ssw_ObjNext( ppNexts, pRepr ) );
Ssw_ObjSetNext( ppNexts, pRepr, pObj );
p->pClassSizes[pRepr->Id]++;
nEntries++;
}
}
// allocate room for classes
p->pMemClasses = ALLOC( Aig_Obj_t *, nEntries + p->nCands1 );
p->pMemClassesFree = p->pMemClasses + nEntries;
// copy the entries into storage in the topological order
nEntries2 = 0;
Aig_ManForEachObj( p->pAig, pObj, i )
{
if ( !Aig_ObjIsNode(pObj) && !Aig_ObjIsPi(pObj) )
continue;
nNodes = p->pClassSizes[pObj->Id];
// skip the nodes that are not representatives of non-trivial classes
if ( nNodes == 0 )
continue;
assert( nNodes > 1 );
// add the nodes to the class in the topological order
ppClassNew = p->pMemClasses + nEntries2;
ppClassNew[0] = pObj;
for ( pTemp = Ssw_ObjNext(ppNexts, pObj), k = 1; pTemp;
pTemp = Ssw_ObjNext(ppNexts, pTemp), k++ )
{
ppClassNew[nNodes-k] = pTemp;
}
// add the class of nodes
p->pClassSizes[pObj->Id] = 0;
Ssw_ObjAddClass( p, pObj, ppClassNew, nNodes );
// increment the number of entries
nEntries2 += nNodes;
}
assert( nEntries == nEntries2 );
free( ppTable );
free( ppNexts );
// now it is time to refine the classes
Ssw_ClassesRefine( p, 1 );
Ssw_ClassesCheck( p );
Ssw_SmlStop( pSml );
// Ssw_ClassesPrint( p, 0 );
if ( fVerbose )
{
PRT( "Collecting candidate equival classes", clock() - clk );
}
return p;
}
/**Function*************************************************************
Synopsis [Creates initial simulation classes.]
Description [Assumes that simulation info is assigned.]
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Cla_t * Ssw_ClassesPrepareSimple( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs )
{
Ssw_Cla_t * p;
Aig_Obj_t * pObj;
int i;
// start the classes
p = Ssw_ClassesStart( pAig );
// go through the nodes
p->nCands1 = 0;
Aig_ManForEachObj( pAig, pObj, i )
{
if ( fLatchCorr )
{
if ( !Saig_ObjIsLo(pAig, pObj) )
continue;
}
else
{
if ( !Aig_ObjIsNode(pObj) && !Saig_ObjIsLo(pAig, pObj) )
continue;
// skip the node with more that the given number of levels
if ( nMaxLevs && (int)pObj->Level > nMaxLevs )
continue;
}
Ssw_ObjSetConst1Cand( pAig, pObj );
p->nCands1++;
}
// allocate room for classes
p->pMemClassesFree = p->pMemClasses = ALLOC( Aig_Obj_t *, p->nCands1 );
// Ssw_ClassesPrint( p, 0 );
return p;
}
/**Function*************************************************************
Synopsis [Creates initial simulation classes.]
Description [Assumes that simulation info is assigned.]
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Cla_t * Ssw_ClassesPrepareTargets( Aig_Man_t * pAig )
{
Ssw_Cla_t * p;
Aig_Obj_t * pObj;
int i;
// start the classes
p = Ssw_ClassesStart( pAig );
// go through the nodes
p->nCands1 = 0;
Saig_ManForEachPo( pAig, pObj, i )
{
Ssw_ObjSetConst1Cand( pAig, Aig_ObjFanin0(pObj) );
p->nCands1++;
}
// allocate room for classes
p->pMemClassesFree = p->pMemClasses = ALLOC( Aig_Obj_t *, p->nCands1 );
// Ssw_ClassesPrint( p, 0 );
return p;
}
/**Function*************************************************************
Synopsis [Creates classes from the temporary representation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Cla_t * Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses )
{
Ssw_Cla_t * p;
Aig_Obj_t ** ppClassNew;
Aig_Obj_t * pObj, * pRepr, * pPrev;
int i, k, nTotalObjs, nEntries, Entry;
// start the classes
p = Ssw_ClassesStart( pAig );
// count the number of entries in the classes
nTotalObjs = 0;
for ( i = 0; i < Aig_ManObjNumMax(pAig); i++ )
nTotalObjs += pvClasses[i] ? Vec_IntSize(pvClasses[i]) : 0;
// allocate memory for classes
p->pMemClasses = ALLOC( Aig_Obj_t *, nTotalObjs );
// create constant-1 class
if ( pvClasses[0] )
Vec_IntForEachEntry( pvClasses[0], Entry, i )
{
assert( (i == 0) == (Entry == 0) );
if ( i == 0 )
continue;
pObj = Aig_ManObj( pAig, Entry );
Ssw_ObjSetConst1Cand( pAig, pObj );
p->nCands1++;
}
// create classes
nEntries = 0;
for ( i = 1; i < Aig_ManObjNumMax(pAig); i++ )
{
if ( pvClasses[i] == NULL )
continue;
// get room for storing the class
ppClassNew = p->pMemClasses + nEntries;
nEntries += Vec_IntSize( pvClasses[i] );
// store the nodes of the class
pPrev = pRepr = Aig_ManObj( pAig, Vec_IntEntry(pvClasses[i],0) );
ppClassNew[0] = pRepr;
Vec_IntForEachEntryStart( pvClasses[i], Entry, k, 1 )
{
pObj = Aig_ManObj( pAig, Entry );
assert( pPrev->Id < pObj->Id );
pPrev = pObj;
ppClassNew[k] = pObj;
Aig_ObjSetRepr( pAig, pObj, pRepr );
}
// create new class
Ssw_ObjAddClass( p, pRepr, ppClassNew, Vec_IntSize(pvClasses[i]) );
}
// prepare room for new classes
p->pMemClassesFree = p->pMemClasses + nEntries;
Ssw_ClassesCheck( p );
// Ssw_ClassesPrint( p, 0 );
return p;
}
/**Function*************************************************************
Synopsis [Iteratively refines the classes after simulation.]
Description [Returns the number of refinements performed.]
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pReprOld, int fRecursive )
{
Aig_Obj_t ** pClassOld, ** pClassNew;
Aig_Obj_t * pObj, * pReprNew;
int i;
// split the class
Vec_PtrClear( p->vClassOld );
Vec_PtrClear( p->vClassNew );
Ssw_ClassForEachNode( p, pReprOld, pObj, i )
if ( p->pFuncNodesAreEqual(p->pManData, pReprOld, pObj) )
Vec_PtrPush( p->vClassOld, pObj );
else
Vec_PtrPush( p->vClassNew, pObj );
// check if splitting happened
if ( Vec_PtrSize(p->vClassNew) == 0 )
return 0;
// remember that this class is refined
Ssw_ClassForEachNode( p, pReprOld, pObj, i )
Vec_PtrPush( p->vRefined, pObj );
// get the new representative
pReprNew = Vec_PtrEntry( p->vClassNew, 0 );
assert( Vec_PtrSize(p->vClassOld) > 0 );
assert( Vec_PtrSize(p->vClassNew) > 0 );
// create old class
pClassOld = Ssw_ObjRemoveClass( p, pReprOld );
Vec_PtrForEachEntry( p->vClassOld, pObj, i )
{
pClassOld[i] = pObj;
Aig_ObjSetRepr( p->pAig, pObj, i? pReprOld : NULL );
}
// create new class
pClassNew = pClassOld + i;
Vec_PtrForEachEntry( p->vClassNew, pObj, i )
{
pClassNew[i] = pObj;
Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL );
}
// put classes back
if ( Vec_PtrSize(p->vClassOld) > 1 )
Ssw_ObjAddClass( p, pReprOld, pClassOld, Vec_PtrSize(p->vClassOld) );
if ( Vec_PtrSize(p->vClassNew) > 1 )
Ssw_ObjAddClass( p, pReprNew, pClassNew, Vec_PtrSize(p->vClassNew) );
// check if the class should be recursively refined
if ( fRecursive && Vec_PtrSize(p->vClassNew) > 1 )
return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 );
return 1;
}
/**Function*************************************************************
Synopsis [Refines the classes after simulation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ClassesRefine( Ssw_Cla_t * p, int fRecursive )
{
Aig_Obj_t ** ppClass;
int i, nRefis = 0;
Ssw_ManForEachClass( p, ppClass, i )
nRefis += Ssw_ClassesRefineOneClass( p, ppClass[0], fRecursive );
return nRefis;
}
/**Function*************************************************************
Synopsis [Refine the group of constant 1 nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecursive )
{
Aig_Obj_t * pObj, * pReprNew, ** ppClassNew;
int i;
if ( Vec_PtrSize(vRoots) == 0 )
return 0;
// collect the nodes to be refined
Vec_PtrClear( p->vClassNew );
Vec_PtrForEachEntry( vRoots, pObj, i )
if ( !p->pFuncNodeIsConst( p->pManData, pObj ) )
Vec_PtrPush( p->vClassNew, pObj );
// check if there is a new class
if ( Vec_PtrSize(p->vClassNew) == 0 )
return 0;
p->nCands1 -= Vec_PtrSize(p->vClassNew);
pReprNew = Vec_PtrEntry( p->vClassNew, 0 );
Aig_ObjSetRepr( p->pAig, pReprNew, NULL );
if ( Vec_PtrSize(p->vClassNew) == 1 )
return 1;
// create a new class composed of these nodes
ppClassNew = p->pMemClassesFree;
p->pMemClassesFree += Vec_PtrSize(p->vClassNew);
Vec_PtrForEachEntry( p->vClassNew, pObj, i )
{
ppClassNew[i] = pObj;
Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL );
}
Ssw_ObjAddClass( p, pReprNew, ppClassNew, Vec_PtrSize(p->vClassNew) );
// refine them recursively
if ( fRecursive )
return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 );
return 1;
}
/**Function*************************************************************
Synopsis [Refine the group of constant 1 nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive )
{
Aig_Obj_t * pObj, * pReprNew, ** ppClassNew;
int i;
// collect the nodes to be refined
Vec_PtrClear( p->vClassNew );
for ( i = 0; i < Vec_PtrSize(p->pAig->vObjs); i++ )
if ( p->pAig->pReprs[i] == Aig_ManConst1(p->pAig) )
{
pObj = Aig_ManObj( p->pAig, i );
if ( !p->pFuncNodeIsConst( p->pManData, pObj ) )
{
Vec_PtrPush( p->vClassNew, pObj );
Vec_PtrPush( p->vRefined, pObj );
}
}
// check if there is a new class
if ( Vec_PtrSize(p->vClassNew) == 0 )
return 0;
p->nCands1 -= Vec_PtrSize(p->vClassNew);
pReprNew = Vec_PtrEntry( p->vClassNew, 0 );
Aig_ObjSetRepr( p->pAig, pReprNew, NULL );
if ( Vec_PtrSize(p->vClassNew) == 1 )
return 1;
// create a new class composed of these nodes
ppClassNew = p->pMemClassesFree;
p->pMemClassesFree += Vec_PtrSize(p->vClassNew);
Vec_PtrForEachEntry( p->vClassNew, pObj, i )
{
ppClassNew[i] = pObj;
Aig_ObjSetRepr( p->pAig, pObj, i? pReprNew : NULL );
}
Ssw_ObjAddClass( p, pReprNew, ppClassNew, Vec_PtrSize(p->vClassNew) );
// refine them recursively
if ( fRecursive )
return 1 + Ssw_ClassesRefineOneClass( p, pReprNew, 1 );
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswCnf.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [Computation of CNF.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswCnf.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Addes clauses to the solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_AddClausesMux( Ssw_Man_t * p, Aig_Obj_t * pNode )
{
Aig_Obj_t * pNodeI, * pNodeT, * pNodeE;
int pLits[4], RetValue, VarF, VarI, VarT, VarE, fCompT, fCompE;
assert( !Aig_IsComplement( pNode ) );
assert( Aig_ObjIsMuxType( pNode ) );
// get nodes (I = if, T = then, E = else)
pNodeI = Aig_ObjRecognizeMux( pNode, &pNodeT, &pNodeE );
// get the variable numbers
VarF = Ssw_ObjSatNum(p,pNode);
VarI = Ssw_ObjSatNum(p,pNodeI);
VarT = Ssw_ObjSatNum(p,Aig_Regular(pNodeT));
VarE = Ssw_ObjSatNum(p,Aig_Regular(pNodeE));
// get the complementation flags
fCompT = Aig_IsComplement(pNodeT);
fCompE = Aig_IsComplement(pNodeE);
// f = ITE(i, t, e)
// i' + t' + f
// i' + t + f'
// i + e' + f
// i + e + f'
// create four clauses
pLits[0] = toLitCond(VarI, 1);
pLits[1] = toLitCond(VarT, 1^fCompT);
pLits[2] = toLitCond(VarF, 0);
if ( p->pPars->fPolarFlip )
{
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
}
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
assert( RetValue );
pLits[0] = toLitCond(VarI, 1);
pLits[1] = toLitCond(VarT, 0^fCompT);
pLits[2] = toLitCond(VarF, 1);
if ( p->pPars->fPolarFlip )
{
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeT)->fPhase ) pLits[1] = lit_neg( pLits[1] );
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
}
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
assert( RetValue );
pLits[0] = toLitCond(VarI, 0);
pLits[1] = toLitCond(VarE, 1^fCompE);
pLits[2] = toLitCond(VarF, 0);
if ( p->pPars->fPolarFlip )
{
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
}
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
assert( RetValue );
pLits[0] = toLitCond(VarI, 0);
pLits[1] = toLitCond(VarE, 0^fCompE);
pLits[2] = toLitCond(VarF, 1);
if ( p->pPars->fPolarFlip )
{
if ( pNodeI->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
}
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
assert( RetValue );
// two additional clauses
// t' & e' -> f'
// t & e -> f
// t + e + f'
// t' + e' + f
if ( VarT == VarE )
{
// assert( fCompT == !fCompE );
return;
}
pLits[0] = toLitCond(VarT, 0^fCompT);
pLits[1] = toLitCond(VarE, 0^fCompE);
pLits[2] = toLitCond(VarF, 1);
if ( p->pPars->fPolarFlip )
{
if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
}
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
assert( RetValue );
pLits[0] = toLitCond(VarT, 1^fCompT);
pLits[1] = toLitCond(VarE, 1^fCompE);
pLits[2] = toLitCond(VarF, 0);
if ( p->pPars->fPolarFlip )
{
if ( Aig_Regular(pNodeT)->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( Aig_Regular(pNodeE)->fPhase ) pLits[1] = lit_neg( pLits[1] );
if ( pNode->fPhase ) pLits[2] = lit_neg( pLits[2] );
}
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 3 );
assert( RetValue );
}
/**Function*************************************************************
Synopsis [Addes clauses to the solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_AddClausesSuper( Ssw_Man_t * p, Aig_Obj_t * pNode, Vec_Ptr_t * vSuper )
{
Aig_Obj_t * pFanin;
int * pLits, nLits, RetValue, i;
assert( !Aig_IsComplement(pNode) );
assert( Aig_ObjIsNode( pNode ) );
// create storage for literals
nLits = Vec_PtrSize(vSuper) + 1;
pLits = ALLOC( int, nLits );
// suppose AND-gate is A & B = C
// add !A => !C or A + !C
Vec_PtrForEachEntry( vSuper, pFanin, i )
{
pLits[0] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), Aig_IsComplement(pFanin));
pLits[1] = toLitCond(Ssw_ObjSatNum(p,pNode), 1);
if ( p->pPars->fPolarFlip )
{
if ( Aig_Regular(pFanin)->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( pNode->fPhase ) pLits[1] = lit_neg( pLits[1] );
}
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
assert( RetValue );
}
// add A & B => C or !A + !B + C
Vec_PtrForEachEntry( vSuper, pFanin, i )
{
pLits[i] = toLitCond(Ssw_ObjSatNum(p,Aig_Regular(pFanin)), !Aig_IsComplement(pFanin));
if ( p->pPars->fPolarFlip )
{
if ( Aig_Regular(pFanin)->fPhase ) pLits[i] = lit_neg( pLits[i] );
}
}
pLits[nLits-1] = toLitCond(Ssw_ObjSatNum(p,pNode), 0);
if ( p->pPars->fPolarFlip )
{
if ( pNode->fPhase ) pLits[nLits-1] = lit_neg( pLits[nLits-1] );
}
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + nLits );
assert( RetValue );
free( pLits );
}
/**Function*************************************************************
Synopsis [Collects the supergate.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_CollectSuper_rec( Aig_Obj_t * pObj, Vec_Ptr_t * vSuper, int fFirst, int fUseMuxes )
{
// if the new node is complemented or a PI, another gate begins
if ( Aig_IsComplement(pObj) || Aig_ObjIsPi(pObj) ||
(!fFirst && Aig_ObjRefs(pObj) > 1) ||
(fUseMuxes && Aig_ObjIsMuxType(pObj)) )
{
Vec_PtrPushUnique( vSuper, pObj );
return;
}
// go through the branches
Ssw_CollectSuper_rec( Aig_ObjChild0(pObj), vSuper, 0, fUseMuxes );
Ssw_CollectSuper_rec( Aig_ObjChild1(pObj), vSuper, 0, fUseMuxes );
}
/**Function*************************************************************
Synopsis [Collects the supergate.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_CollectSuper( Aig_Obj_t * pObj, int fUseMuxes, Vec_Ptr_t * vSuper )
{
assert( !Aig_IsComplement(pObj) );
assert( !Aig_ObjIsPi(pObj) );
Vec_PtrClear( vSuper );
Ssw_CollectSuper_rec( pObj, vSuper, 1, fUseMuxes );
}
/**Function*************************************************************
Synopsis [Updates the solver clause database.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ObjAddToFrontier( Ssw_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vFrontier )
{
assert( !Aig_IsComplement(pObj) );
if ( Ssw_ObjSatNum(p,pObj) )
return;
assert( Ssw_ObjSatNum(p,pObj) == 0 );
if ( Aig_ObjIsConst1(pObj) )
return;
if ( p->pPars->fLatchCorrOpt )
{
Vec_PtrPush( p->vUsedNodes, pObj );
if ( Aig_ObjIsPi(pObj) )
Vec_PtrPush( p->vUsedPis, pObj );
}
Ssw_ObjSetSatNum( p, pObj, p->nSatVars++ );
sat_solver_setnvars( p->pSat, 100 * (1 + p->nSatVars / 100) );
if ( Aig_ObjIsNode(pObj) )
Vec_PtrPush( vFrontier, pObj );
}
/**Function*************************************************************
Synopsis [Updates the solver clause database.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_CnfNodeAddToSolver( Ssw_Man_t * p, Aig_Obj_t * pObj )
{
Vec_Ptr_t * vFrontier;
Aig_Obj_t * pNode, * pFanin;
int i, k, fUseMuxes = 1;
// quit if CNF is ready
if ( Ssw_ObjSatNum(p,pObj) )
return;
// start the frontier
vFrontier = Vec_PtrAlloc( 100 );
Ssw_ObjAddToFrontier( p, pObj, vFrontier );
// explore nodes in the frontier
Vec_PtrForEachEntry( vFrontier, pNode, i )
{
// create the supergate
assert( Ssw_ObjSatNum(p,pNode) );
if ( fUseMuxes && Aig_ObjIsMuxType(pNode) )
{
Vec_PtrClear( p->vFanins );
Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin0(pNode) ) );
Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin0( Aig_ObjFanin1(pNode) ) );
Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin0(pNode) ) );
Vec_PtrPushUnique( p->vFanins, Aig_ObjFanin1( Aig_ObjFanin1(pNode) ) );
Vec_PtrForEachEntry( p->vFanins, pFanin, k )
Ssw_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier );
Ssw_AddClausesMux( p, pNode );
}
else
{
Ssw_CollectSuper( pNode, fUseMuxes, p->vFanins );
Vec_PtrForEachEntry( p->vFanins, pFanin, k )
Ssw_ObjAddToFrontier( p, Aig_Regular(pFanin), vFrontier );
Ssw_AddClausesSuper( p, pNode, p->vFanins );
}
assert( Vec_PtrSize(p->vFanins) > 1 );
}
Vec_PtrFree( vFrontier );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswCore.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [The core procedures.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswCore.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [This procedure sets default parameters.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManSetDefaultParams( Ssw_Pars_t * p )
{
memset( p, 0, sizeof(Ssw_Pars_t) );
p->nPartSize = 0; // size of the partition
p->nOverSize = 0; // size of the overlap between partitions
p->nFramesK = 1; // the induction depth
p->nFramesAddSim = 0; // additional frames to simulate
p->nConstrs = 0; // treat the last nConstrs POs as seq constraints
p->nBTLimit = 1000; // conflict limit at a node
p->nMinDomSize = 100; // min clock domain considered for optimization
p->fPolarFlip = 0; // uses polarity adjustment
p->fSkipCheck = 0; // do not run equivalence check for unaffected cones
p->fLatchCorr = 0; // performs register correspondence
p->fSemiFormal = 0; // enable semiformal filtering
p->fUniqueness = 0; // enable uniqueness constraints
p->fVerbose = 0; // verbose stats
// latch correspondence
p->fLatchCorrOpt = 0; // performs optimized register correspondence
p->nSatVarMax = 1000; // the max number of SAT variables
p->nRecycleCalls = 50; // calls to perform before recycling SAT solver
// return values
p->nIters = 0; // the number of iterations performed
}
/**Function*************************************************************
Synopsis [This procedure sets default parameters.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManSetDefaultParamsLcorr( Ssw_Pars_t * p )
{
Ssw_ManSetDefaultParams( p );
p->fLatchCorrOpt = 1;
p->nBTLimit = 10000;
}
/**Function*************************************************************
Synopsis [Performs computation of signal correspondence with constraints.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p )
{
int nSatProof, nSatCallsSat, nRecycles, nSatFailsReal;
Aig_Man_t * pAigNew;
int RetValue, nIter;
int clk, clkTotal = clock();
// get the starting stats
p->nLitsBeg = Ssw_ClassesLitNum( p->ppClasses );
p->nNodesBeg = Aig_ManNodeNum(p->pAig);
p->nRegsBeg = Aig_ManRegNum(p->pAig);
// refine classes using BMC
if ( p->pPars->fVerbose )
{
printf( "Before BMC: " );
Ssw_ClassesPrint( p->ppClasses, 0 );
}
if ( !p->pPars->fLatchCorr )
{
Ssw_ManSweepBmc( p );
Ssw_ManCleanup( p );
}
if ( p->pPars->fVerbose )
{
printf( "After BMC: " );
Ssw_ClassesPrint( p->ppClasses, 0 );
}
// apply semi-formal filtering
if ( p->pPars->fSemiFormal )
{
Aig_Man_t * pSRed;
Ssw_FilterUsingBmc( p, 0, 2000, p->pPars->fVerbose );
// Ssw_FilterUsingBmc( p, 1, 100000, p->pPars->fVerbose );
pSRed = Ssw_SpeculativeReduction( p );
Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL );
Aig_ManStop( pSRed );
}
// refine classes using induction
nSatProof = nSatCallsSat = nRecycles = nSatFailsReal = 0;
for ( nIter = 0; ; nIter++ )
{
clk = clock();
if ( p->pPars->fLatchCorrOpt )
{
RetValue = Ssw_ManSweepLatch( p );
if ( p->pPars->fVerbose )
{
printf( "%3d : Const = %6d. Cl = %6d. Pr = %5d. Cex = %5d. Rcl = %3d. F = %3d. ",
nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses),
p->nSatProof-nSatProof, p->nSatCallsSat-nSatCallsSat,
p->nRecycles-nRecycles, p->nSatFailsReal-nSatFailsReal );
PRT( "T", clock() - clk );
nSatProof = p->nSatProof;
nSatCallsSat = p->nSatCallsSat;
nRecycles = p->nRecycles;
nSatFailsReal = p->nSatFailsReal;
}
}
else
{
// if ( nIter == 6 )
// p->pPars->fUniqueness = 0;
RetValue = Ssw_ManSweep( p );
if ( p->pPars->fVerbose )
{
printf( "%3d : Const = %6d. Cl = %6d. LR = %6d. NR = %6d. U = %3d. F = %2d. ",
nIter, Ssw_ClassesCand1Num(p->ppClasses), Ssw_ClassesClassNum(p->ppClasses),
p->nConstrReduced, Aig_ManNodeNum(p->pFrames), p->nUniques, p->nSatFailsReal );
if ( p->pPars->fSkipCheck )
printf( "Use = %5d. Skip = %5d. ",
p->nRefUse, p->nRefSkip );
PRT( "T", clock() - clk );
}
}
Ssw_ManCleanup( p );
if ( !RetValue )
break;
/*
{
static int Flag = 0;
if ( Flag++ == 4 && nIter == 4 )
{
Aig_Man_t * pSRed;
pSRed = Ssw_SpeculativeReduction( p );
Aig_ManDumpBlif( pSRed, "srm.blif", NULL, NULL );
Aig_ManStop( pSRed );
}
}
*/
}
p->pPars->nIters = nIter + 1;
p->timeTotal = clock() - clkTotal;
pAigNew = Aig_ManDupRepr( p->pAig, 0 );
Aig_ManSeqCleanup( pAigNew );
// get the final stats
p->nLitsEnd = Ssw_ClassesLitNum( p->ppClasses );
p->nNodesEnd = Aig_ManNodeNum(pAigNew);
p->nRegsEnd = Aig_ManRegNum(pAigNew);
return pAigNew;
}
/**Function*************************************************************
Synopsis [Performs computation of signal correspondence with constraints.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ssw_SignalCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
{
Ssw_Pars_t Pars;
Aig_Man_t * pAigNew;
Ssw_Man_t * p;
assert( Aig_ManRegNum(pAig) > 0 );
// reset random numbers
Aig_ManRandom( 1 );
// if parameters are not given, create them
if ( pPars == NULL )
Ssw_ManSetDefaultParams( pPars = &Pars );
// consider the case of empty AIG
if ( Aig_ManNodeNum(pAig) == 0 )
{
pPars->nIters = 0;
// Ntl_ManFinalize() needs the following to satisfy an assertion
Aig_ManReprStart( pAig,Aig_ManObjNumMax(pAig) );
return Aig_ManDupOrdered(pAig);
}
// check and update parameters
if ( pPars->fLatchCorrOpt )
{
pPars->fLatchCorr = 1;
pPars->nFramesAddSim = 0;
}
else
{
assert( pPars->nFramesK > 0 );
if ( pPars->nFramesK > 1 )
pPars->fSkipCheck = 0;
// perform partitioning
if ( (pPars->nPartSize > 0 && pPars->nPartSize < Aig_ManRegNum(pAig))
|| (pAig->vClockDoms && Vec_VecSize(pAig->vClockDoms) > 0) )
return Ssw_SignalCorrespondencePart( pAig, pPars );
}
// start the induction manager
p = Ssw_ManCreate( pAig, pPars );
// compute candidate equivalence classes
// p->pPars->nConstrs = 1;
if ( p->pPars->nConstrs == 0 )
{
// perform one round of seq simulation and generate candidate equivalence classes
p->ppClasses = Ssw_ClassesPrepare( pAig, pPars->fLatchCorr, pPars->nMaxLevs, pPars->fVerbose );
// p->ppClasses = Ssw_ClassesPrepareTargets( pAig );
// p->pSml = Ssw_SmlStart( pAig, 0, p->nFrames + p->pPars->nFramesAddSim, 1 );
p->pSml = Ssw_SmlStart( pAig, 0, 1, 1 );
Ssw_ClassesSetData( p->ppClasses, p->pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord );
}
else
{
// create trivial equivalence classes with all nodes being candidates for constant 1
p->ppClasses = Ssw_ClassesPrepareSimple( pAig, pPars->fLatchCorr, pPars->nMaxLevs );
Ssw_ClassesSetData( p->ppClasses, NULL, NULL, Ssw_SmlObjIsConstBit, Ssw_SmlObjsAreEqualBit );
}
// perform refinement of classes
pAigNew = Ssw_SignalCorrespondenceRefine( p );
// cleanup
Ssw_ManStop( p );
return pAigNew;
}
/**Function*************************************************************
Synopsis [Performs computation of latch correspondence.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ssw_LatchCorrespondence( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
{
Ssw_Pars_t Pars;
if ( pPars == NULL )
Ssw_ManSetDefaultParamsLcorr( pPars = &Pars );
return Ssw_SignalCorrespondence( pAig, pPars );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswInt.h]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [External declarations.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswInt.h,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#ifndef __SSW_INT_H__
#define __SSW_INT_H__
#ifdef __cplusplus
extern "C" {
#endif
////////////////////////////////////////////////////////////////////////
/// INCLUDES ///
////////////////////////////////////////////////////////////////////////
#include "saig.h"
#include "satSolver.h"
#include "ssw.h"
////////////////////////////////////////////////////////////////////////
/// PARAMETERS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// BASIC TYPES ///
////////////////////////////////////////////////////////////////////////
typedef struct Ssw_Man_t_ Ssw_Man_t; // signal correspondence manager
typedef struct Ssw_Cla_t_ Ssw_Cla_t; // equivalence classe manager
typedef struct Ssw_Sml_t_ Ssw_Sml_t; // sequential simulation manager
struct Ssw_Man_t_
{
// parameters
Ssw_Pars_t * pPars; // parameters
int nFrames; // for quick lookup
// AIGs used in the package
Aig_Man_t * pAig; // user-given AIG
Aig_Man_t * pFrames; // final AIG
Aig_Obj_t ** pNodeToFrames; // mapping of AIG nodes into FRAIG nodes
// equivalence classes
Ssw_Cla_t * ppClasses; // equivalence classes of nodes
int fRefined; // is set to 1 when refinement happens
int nRefUse; // the number of equivalences used
int nRefSkip; // the number of equivalences skipped
// SAT solving
sat_solver * pSat; // recyclable SAT solver
int nSatVars; // the counter of SAT variables
Vec_Int_t * vSatVars; // mapping of each node into its SAT var
int nSatVarsTotal; // the total number of SAT vars created
Vec_Ptr_t * vFanins; // fanins of the CNF node
// SAT solving (latch corr only)
Vec_Ptr_t * vUsedNodes; // the nodes with SAT variables
Vec_Ptr_t * vUsedPis; // the PIs with SAT variables
Vec_Ptr_t * vSimInfo; // simulation information for the framed PIs
int nPatterns; // the number of patterns saved
int nSimRounds; // the number of simulation rounds performed
int nCallsCount; // the number of calls in this round
int nCallsDelta; // the number of calls to skip
int nCallsSat; // the number of SAT calls in this round
int nCallsUnsat; // the number of UNSAT calls in this round
int nRecycleCalls; // the number of calls since last recycling
int nRecycles; // the number of time SAT solver was recycled
int nConeMax; // the maximum cone size
// uniqueness
Vec_Ptr_t * vCommon; // the set of common variables in the logic cones
int iOutputLit; // the output literal of the uniqueness constaint
int nUniques; // the number of uniqueness constaints used
// sequential simulator
Ssw_Sml_t * pSml;
// counter example storage
int nPatWords; // the number of words in the counter example
unsigned * pPatWords; // the counter example
unsigned * pPatWords2; // the counter example
// constraints
int nConstrTotal; // the number of total constraints
int nConstrReduced; // the number of reduced constraints
int nStrangers; // the number of strange situations
// SAT calls statistics
int nSatCalls; // the number of SAT calls
int nSatProof; // the number of proofs
int nSatFailsReal; // the number of timeouts
int nSatFailsTotal; // the number of timeouts
int nSatCallsUnsat; // the number of unsat SAT calls
int nSatCallsSat; // the number of sat SAT calls
// node/register/lit statistics
int nLitsBeg;
int nLitsEnd;
int nNodesBeg;
int nNodesEnd;
int nRegsBeg;
int nRegsEnd;
// runtime stats
int timeBmc; // bounded model checking
int timeReduce; // speculative reduction
int timeMarkCones; // marking the cones not to be refined
int timeSimSat; // simulation of the counter-examples
int timeSat; // solving SAT
int timeSatSat; // sat
int timeSatUnsat; // unsat
int timeSatUndec; // undecided
int timeOther; // other runtime
int timeTotal; // total runtime
};
////////////////////////////////////////////////////////////////////////
/// MACRO DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
static inline int Ssw_ObjSatNum( Ssw_Man_t * p, Aig_Obj_t * pObj ) { return Vec_IntEntry( p->vSatVars, pObj->Id ); }
static inline void Ssw_ObjSetSatNum( Ssw_Man_t * p, Aig_Obj_t * pObj, int Num ) { Vec_IntWriteEntryFill( p->vSatVars, pObj->Id, Num ); }
static inline int Ssw_ObjIsConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )
{
return Aig_ObjRepr(pAig, pObj) == Aig_ManConst1(pAig);
}
static inline void Ssw_ObjSetConst1Cand( Aig_Man_t * pAig, Aig_Obj_t * pObj )
{
assert( !Ssw_ObjIsConst1Cand( pAig, pObj ) );
Aig_ObjSetRepr( pAig, pObj, Aig_ManConst1(pAig) );
}
static inline Aig_Obj_t * Ssw_ObjFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { return p->pNodeToFrames[p->nFrames*pObj->Id + i]; }
static inline void Ssw_ObjSetFrame( Ssw_Man_t * p, Aig_Obj_t * pObj, int i, Aig_Obj_t * pNode ) { p->pNodeToFrames[p->nFrames*pObj->Id + i] = pNode; }
static inline Aig_Obj_t * Ssw_ObjChild0Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin0(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin0(pObj), i), Aig_ObjFaninC0(pObj)) : NULL; }
static inline Aig_Obj_t * Ssw_ObjChild1Fra( Ssw_Man_t * p, Aig_Obj_t * pObj, int i ) { assert( !Aig_IsComplement(pObj) ); return Aig_ObjFanin1(pObj)? Aig_NotCond(Ssw_ObjFrame(p, Aig_ObjFanin1(pObj), i), Aig_ObjFaninC1(pObj)) : NULL; }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
/*=== sswAig.c ===================================================*/
extern Aig_Man_t * Ssw_FramesWithClasses( Ssw_Man_t * p );
extern Aig_Man_t * Ssw_SpeculativeReduction( Ssw_Man_t * p );
/*=== sswBmc.c ===================================================*/
extern int Ssw_FilterUsingBmc( Ssw_Man_t * pMan, int fCheckTargets, int nConfMax, int fVerbose );
/*=== sswClass.c =================================================*/
extern Ssw_Cla_t * Ssw_ClassesStart( Aig_Man_t * pAig );
extern void Ssw_ClassesSetData( Ssw_Cla_t * p, void * pManData,
unsigned (*pFuncNodeHash)(void *,Aig_Obj_t *),
int (*pFuncNodeIsConst)(void *,Aig_Obj_t *),
int (*pFuncNodesAreEqual)(void *,Aig_Obj_t *, Aig_Obj_t *) );
extern void Ssw_ClassesStop( Ssw_Cla_t * p );
extern Aig_Man_t * Ssw_ClassesReadAig( Ssw_Cla_t * p );
extern Vec_Ptr_t * Ssw_ClassesGetRefined( Ssw_Cla_t * p );
extern void Ssw_ClassesClearRefined( Ssw_Cla_t * p );
extern int Ssw_ClassesCand1Num( Ssw_Cla_t * p );
extern int Ssw_ClassesClassNum( Ssw_Cla_t * p );
extern int Ssw_ClassesLitNum( Ssw_Cla_t * p );
extern Aig_Obj_t ** Ssw_ClassesReadClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int * pnSize );
extern void Ssw_ClassesCollectClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, Vec_Ptr_t * vClass );
extern void Ssw_ClassesCheck( Ssw_Cla_t * p );
extern void Ssw_ClassesPrint( Ssw_Cla_t * p, int fVeryVerbose );
extern void Ssw_ClassesRemoveNode( Ssw_Cla_t * p, Aig_Obj_t * pObj );
extern Ssw_Cla_t * Ssw_ClassesPrepare( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs, int fVerbose );
extern Ssw_Cla_t * Ssw_ClassesPrepareSimple( Aig_Man_t * pAig, int fLatchCorr, int nMaxLevs );
extern Ssw_Cla_t * Ssw_ClassesPrepareTargets( Aig_Man_t * pAig );
extern Ssw_Cla_t * Ssw_ClassesPreparePairs( Aig_Man_t * pAig, Vec_Int_t ** pvClasses );
extern int Ssw_ClassesRefine( Ssw_Cla_t * p, int fRecursive );
extern int Ssw_ClassesRefineOneClass( Ssw_Cla_t * p, Aig_Obj_t * pRepr, int fRecursive );
extern int Ssw_ClassesRefineConst1Group( Ssw_Cla_t * p, Vec_Ptr_t * vRoots, int fRecursive );
extern int Ssw_ClassesRefineConst1( Ssw_Cla_t * p, int fRecursive );
/*=== sswCnf.c ===================================================*/
extern void Ssw_CnfNodeAddToSolver( Ssw_Man_t * p, Aig_Obj_t * pObj );
/*=== sswCore.c ===================================================*/
extern Aig_Man_t * Ssw_SignalCorrespondenceRefine( Ssw_Man_t * p );
/*=== sswLcorr.c ==========================================================*/
extern int Ssw_ManSweepLatch( Ssw_Man_t * p );
/*=== sswMan.c ===================================================*/
extern Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars );
extern void Ssw_ManCleanup( Ssw_Man_t * p );
extern void Ssw_ManStop( Ssw_Man_t * p );
extern void Ssw_ManStartSolver( Ssw_Man_t * p );
/*=== sswSat.c ===================================================*/
extern int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
extern int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew );
/*=== sswSim.c ===================================================*/
extern unsigned Ssw_SmlObjHashWord( Ssw_Sml_t * p, Aig_Obj_t * pObj );
extern int Ssw_SmlObjIsConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj );
extern int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
extern int Ssw_SmlObjIsConstBit( void * p, Aig_Obj_t * pObj );
extern int Ssw_SmlObjsAreEqualBit( void * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 );
extern Ssw_Sml_t * Ssw_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame );
extern void Ssw_SmlClean( Ssw_Sml_t * p );
extern void Ssw_SmlStop( Ssw_Sml_t * p );
extern void Ssw_SmlObjAssignConst( Ssw_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame );
extern unsigned Ssw_SmlObjGetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iWord, int iFrame );
extern void Ssw_SmlObjSetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, unsigned Word, int iWord, int iFrame );
extern void Ssw_SmlAssignDist1Plus( Ssw_Sml_t * p, unsigned * pPat );
extern void Ssw_SmlSimulateOne( Ssw_Sml_t * p );
extern void Ssw_SmlSimulateOneFrame( Ssw_Sml_t * p );
extern Ssw_Sml_t * Ssw_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nWords );
/*=== sswSimSat.c ===================================================*/
extern void Ssw_ManResimulateBit( Ssw_Man_t * p, Aig_Obj_t * pObj, Aig_Obj_t * pRepr );
extern void Ssw_ManResimulateWord( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f );
extern void Ssw_ManResimulateWord2( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f );
/*=== sswSweep.c ===================================================*/
extern int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f );
extern int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc );
extern int Ssw_ManSweepBmc( Ssw_Man_t * p );
extern int Ssw_ManSweep( Ssw_Man_t * p );
/*=== sswUnique.c ===================================================*/
extern int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj );
extern int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 );
#ifdef __cplusplus
}
#endif
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswLcorr.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [Latch correspondence.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswLcorr.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
//#include "bar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Recycles the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManSatSolverRecycle( Ssw_Man_t * p )
{
int Lit;
if ( p->pSat )
{
Aig_Obj_t * pObj;
int i;
Vec_PtrForEachEntry( p->vUsedNodes, pObj, i )
Ssw_ObjSetSatNum( p, pObj, 0 );
Vec_PtrClear( p->vUsedNodes );
Vec_PtrClear( p->vUsedPis );
// memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAigTotal) );
sat_solver_delete( p->pSat );
}
p->pSat = sat_solver_new();
sat_solver_setnvars( p->pSat, 1000 );
// var 0 is not used
// var 1 is reserved for const1 node - add the clause
p->nSatVars = 1;
// p->nSatVars = 0;
Lit = toLit( p->nSatVars );
if ( p->pPars->fPolarFlip )
Lit = lit_neg( Lit );
sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
Ssw_ObjSetSatNum( p, Aig_ManConst1(p->pFrames), p->nSatVars++ );
p->nRecycles++;
p->nRecycleCalls = 0;
}
/**Function*************************************************************
Synopsis [Tranfers simulation information from FRAIG to AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManSweepTransfer( Ssw_Man_t * p )
{
Aig_Obj_t * pObj, * pObjFraig;
unsigned * pInfo;
int i;
// transfer simulation information
Aig_ManForEachPi( p->pAig, pObj, i )
{
pObjFraig = Ssw_ObjFrame( p, pObj, 0 );
if ( pObjFraig == Aig_ManConst0(p->pFrames) )
{
Ssw_SmlObjAssignConst( p->pSml, pObj, 0, 0 );
continue;
}
assert( !Aig_IsComplement(pObjFraig) );
assert( Aig_ObjIsPi(pObjFraig) );
pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObjFraig) );
Ssw_SmlObjSetWord( p->pSml, pObj, pInfo[0], 0, 0 );
}
}
/**Function*************************************************************
Synopsis [Performs one round of simulation with counter-examples.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManSweepResimulate( Ssw_Man_t * p )
{
int RetValue1, RetValue2, clk = clock();
// transfer PI simulation information from storage
Ssw_ManSweepTransfer( p );
// simulate internal nodes
Ssw_SmlSimulateOneFrame( p->pSml );
// check equivalence classes
RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
// prepare simulation info for the next round
Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
p->nPatterns = 0;
p->nSimRounds++;
p->timeSimSat += clock() - clk;
return RetValue1 > 0 || RetValue2 > 0;
}
/**Function*************************************************************
Synopsis [Saves one counter-example into internal storage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlAddPattern( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pCand )
{
Aig_Obj_t * pObj;
unsigned * pInfo;
int i, nVarNum, Value;
Vec_PtrForEachEntry( p->vUsedPis, pObj, i )
{
nVarNum = Ssw_ObjSatNum( p, pObj );
assert( nVarNum > 0 );
Value = sat_solver_var_value( p->pSat, nVarNum );
if ( Value == 0 )
continue;
pInfo = Vec_PtrEntry( p->vSimInfo, Aig_ObjPioNum(pObj) );
Aig_InfoSetBit( pInfo, p->nPatterns );
}
}
/**Function*************************************************************
Synopsis [Builds fraiged logic cone of the node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManBuildCone_rec( Ssw_Man_t * p, Aig_Obj_t * pObj )
{
Aig_Obj_t * pObjNew;
assert( !Aig_IsComplement(pObj) );
if ( Ssw_ObjFrame( p, pObj, 0 ) )
return;
assert( Aig_ObjIsNode(pObj) );
Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObj) );
Ssw_ManBuildCone_rec( p, Aig_ObjFanin1(pObj) );
pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, 0), Ssw_ObjChild1Fra(p, pObj, 0) );
Ssw_ObjSetFrame( p, pObj, 0, pObjNew );
}
/**Function*************************************************************
Synopsis [Recycles the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManSweepLatchOne( Ssw_Man_t * p, Aig_Obj_t * pObjRepr, Aig_Obj_t * pObj )
{
Aig_Obj_t * pObjFraig, * pObjReprFraig, * pObjLi;
int RetValue, clk;
assert( Aig_ObjIsPi(pObj) );
assert( Aig_ObjIsPi(pObjRepr) || Aig_ObjIsConst1(pObjRepr) );
// check if it makes sense to skip some calls
if ( p->nCallsCount > 100 && p->nCallsUnsat < p->nCallsSat )
{
if ( ++p->nCallsDelta < 0 )
return;
}
p->nCallsDelta = 0;
clk = clock();
// get the fraiged node
pObjLi = Saig_ObjLoToLi( p->pAig, pObj );
Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) );
pObjFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 );
// get the fraiged representative
if ( Aig_ObjIsPi(pObjRepr) )
{
pObjLi = Saig_ObjLoToLi( p->pAig, pObjRepr );
Ssw_ManBuildCone_rec( p, Aig_ObjFanin0(pObjLi) );
pObjReprFraig = Ssw_ObjChild0Fra( p, pObjLi, 0 );
}
else
pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, 0 );
p->timeReduce += clock() - clk;
// if the fraiged nodes are the same, return
if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
return;
p->nRecycleCalls++;
p->nCallsCount++;
// check equivalence of the two nodes
if ( (pObj->fPhase == pObjRepr->fPhase) != (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) )
{
p->nPatterns++;
p->nStrangers++;
p->fRefined = 1;
}
else
{
RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
if ( RetValue == 1 ) // proved equivalence
{
p->nCallsUnsat++;
return;
}
if ( RetValue == -1 ) // timed out
{
Ssw_ClassesRemoveNode( p->ppClasses, pObj );
p->nCallsUnsat++;
p->fRefined = 1;
return;
}
else // disproved equivalence
{
Ssw_SmlAddPattern( p, pObjRepr, pObj );
p->nPatterns++;
p->nCallsSat++;
p->fRefined = 1;
}
}
}
/**Function*************************************************************
Synopsis [Performs one iteration of sweeping latches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManSweepLatch( Ssw_Man_t * p )
{
// Bar_Progress_t * pProgress = NULL;
Vec_Ptr_t * vClass;
Aig_Obj_t * pObj, * pRepr, * pTemp;
int i, k;
// start the timeframe
p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) );
// map constants and PIs
Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), 0, Aig_ManConst1(p->pFrames) );
Saig_ManForEachPi( p->pAig, pObj, i )
Ssw_ObjSetFrame( p, pObj, 0, Aig_ObjCreatePi(p->pFrames) );
// implement equivalence classes
Saig_ManForEachLo( p->pAig, pObj, i )
{
pRepr = Aig_ObjRepr( p->pAig, pObj );
if ( pRepr == NULL )
{
pTemp = Aig_ObjCreatePi(p->pFrames);
pTemp->pData = pObj;
}
else
pTemp = Aig_NotCond( Ssw_ObjFrame(p, pRepr, 0), pRepr->fPhase ^ pObj->fPhase );
Ssw_ObjSetFrame( p, pObj, 0, pTemp );
}
Aig_ManSetPioNumbers( p->pFrames );
// prepare simulation info
assert( p->vSimInfo == NULL );
p->vSimInfo = Vec_PtrAllocSimInfo( Aig_ManPiNum(p->pFrames), 1 );
Vec_PtrCleanSimInfo( p->vSimInfo, 0, 1 );
// go through the registers
// if ( p->pPars->fVerbose )
// pProgress = Bar_ProgressStart( stdout, Aig_ManRegNum(p->pAig) );
vClass = Vec_PtrAlloc( 100 );
p->fRefined = 0;
p->nCallsCount = p->nCallsSat = p->nCallsUnsat = 0;
Saig_ManForEachLo( p->pAig, pObj, i )
{
// if ( p->pPars->fVerbose )
// Bar_ProgressUpdate( pProgress, i, NULL );
// consider the case of constant candidate
if ( Ssw_ObjIsConst1Cand( p->pAig, pObj ) )
Ssw_ManSweepLatchOne( p, Aig_ManConst1(p->pAig), pObj );
else
{
// consider the case of equivalence class
Ssw_ClassesCollectClass( p->ppClasses, pObj, vClass );
if ( Vec_PtrSize(vClass) == 0 )
continue;
// try to prove equivalences in this class
Vec_PtrForEachEntry( vClass, pTemp, k )
if ( Aig_ObjRepr(p->pAig, pTemp) == pObj )
{
Ssw_ManSweepLatchOne( p, pObj, pTemp );
if ( p->nPatterns == 32 )
break;
}
}
// resimulate
if ( p->nPatterns == 32 )
Ssw_ManSweepResimulate( p );
// attempt recycling the SAT solver
if ( p->pPars->nSatVarMax &&
p->nSatVars > p->pPars->nSatVarMax &&
p->nRecycleCalls > p->pPars->nRecycleCalls )
Ssw_ManSatSolverRecycle( p );
}
// resimulate
if ( p->nPatterns > 0 )
Ssw_ManSweepResimulate( p );
// cleanup
Vec_PtrFree( vClass );
p->nSatFailsTotal += p->nSatFailsReal;
// if ( p->pPars->fVerbose )
// Bar_ProgressStop( pProgress );
// cleanup
// Ssw_ClassesCheck( p->ppClasses );
return p->fRefined;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswMan.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [Calls to the SAT solver.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswMan.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Creates the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Man_t * Ssw_ManCreate( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
{
Ssw_Man_t * p;
// prepare the sequential AIG
assert( Saig_ManRegNum(pAig) > 0 );
Aig_ManFanoutStart( pAig );
Aig_ManSetPioNumbers( pAig );
// create interpolation manager
p = ALLOC( Ssw_Man_t, 1 );
memset( p, 0, sizeof(Ssw_Man_t) );
p->pPars = pPars;
p->pAig = pAig;
p->nFrames = pPars->nFramesK + 1;
p->pNodeToFrames = CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(p->pAig) * p->nFrames );
// SAT solving
p->vSatVars = Vec_IntStart( Aig_ManObjNumMax(p->pAig) * (p->nFrames+1) );
p->vFanins = Vec_PtrAlloc( 100 );
// SAT solving (latch corr only)
p->vUsedNodes = Vec_PtrAlloc( 1000 );
p->vUsedPis = Vec_PtrAlloc( 1000 );
p->vCommon = Vec_PtrAlloc( 100 );
p->iOutputLit = -1;
// allocate storage for sim pattern
p->nPatWords = Aig_BitWordNum( Saig_ManPiNum(pAig) * p->nFrames + Saig_ManRegNum(pAig) );
p->pPatWords = ALLOC( unsigned, p->nPatWords );
p->pPatWords2 = ALLOC( unsigned, p->nPatWords );
return p;
}
/**Function*************************************************************
Synopsis [Prints stats of the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManCountEquivs( Ssw_Man_t * p )
{
Aig_Obj_t * pObj;
int i, nEquivs = 0;
Aig_ManForEachObj( p->pAig, pObj, i )
nEquivs += ( Aig_ObjRepr(p->pAig, pObj) != NULL );
return nEquivs;
}
/**Function*************************************************************
Synopsis [Prints stats of the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManPrintStats( Ssw_Man_t * p )
{
double nMemory = 1.0*Aig_ManObjNumMax(p->pAig)*p->nFrames*(2*sizeof(int)+2*sizeof(void*))/(1<<20);
printf( "Parameters: F = %d. AddF = %d. C-lim = %d. Constr = %d. MaxLev = %d. Mem = %0.2f Mb.\n",
p->pPars->nFramesK, p->pPars->nFramesAddSim, p->pPars->nBTLimit, p->pPars->nConstrs, p->pPars->nMaxLevs, nMemory );
printf( "AIG : PI = %d. PO = %d. Latch = %d. Node = %d. Ave SAT vars = %d.\n",
Saig_ManPiNum(p->pAig), Saig_ManPoNum(p->pAig), Saig_ManRegNum(p->pAig), Aig_ManNodeNum(p->pAig),
p->nSatVarsTotal/p->pPars->nIters );
printf( "SAT calls : Proof = %d. Cex = %d. Fail = %d. Equivs = %d. Str = %d.\n",
p->nSatProof, p->nSatCallsSat, p->nSatFailsTotal, Ssw_ManCountEquivs(p), p->nStrangers );
printf( "SAT solver: Vars = %d. Max cone = %d. Recycles = %d. Rounds = %d.\n",
p->nSatVars, p->nConeMax, p->nRecycles, p->nSimRounds );
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:1),
p->nRegsBeg, p->nRegsEnd, 100.0*(p->nRegsBeg-p->nRegsEnd)/(p->nRegsBeg?p->nRegsBeg:1) );
p->timeOther = p->timeTotal-p->timeBmc-p->timeReduce-p->timeMarkCones-p->timeSimSat-p->timeSat;
PRTP( "BMC ", p->timeBmc, p->timeTotal );
PRTP( "Spec reduce", p->timeReduce, p->timeTotal );
PRTP( "Mark cones ", p->timeMarkCones, p->timeTotal );
PRTP( "Sim SAT ", p->timeSimSat, p->timeTotal );
PRTP( "SAT solving", p->timeSat, p->timeTotal );
PRTP( " unsat ", p->timeSatUnsat, p->timeTotal );
PRTP( " sat ", p->timeSatSat, p->timeTotal );
PRTP( " undecided", p->timeSatUndec, p->timeTotal );
PRTP( "Other ", p->timeOther, p->timeTotal );
PRTP( "TOTAL ", p->timeTotal, p->timeTotal );
}
/**Function*************************************************************
Synopsis [Frees the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManCleanup( Ssw_Man_t * p )
{
if ( p->pFrames )
{
Aig_ManStop( p->pFrames );
p->pFrames = NULL;
memset( p->pNodeToFrames, 0, sizeof(Aig_Obj_t *) * Aig_ManObjNumMax(p->pAig) * p->nFrames );
}
if ( p->pSat )
{
int i;
// printf( "Vars = %d. Clauses = %d. Learnts = %d.\n", p->pSat->size, p->pSat->clauses.size, p->pSat->learnts.size );
p->nSatVarsTotal += p->pSat->size;
sat_solver_delete( p->pSat );
p->pSat = NULL;
// memset( p->pSatVars, 0, sizeof(int) * Aig_ManObjNumMax(p->pAig) * (p->nFrames+1) );
for ( i = 0; i < Vec_IntSize(p->vSatVars); i++ )
p->vSatVars->pArray[i] = 0;
}
if ( p->vSimInfo )
{
Vec_PtrFree( p->vSimInfo );
p->vSimInfo = NULL;
}
p->nConstrTotal = 0;
p->nConstrReduced = 0;
}
/**Function*************************************************************
Synopsis [Frees the manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManStop( Ssw_Man_t * p )
{
Aig_ManCleanMarkA( p->pAig );
Aig_ManCleanMarkB( p->pAig );
if ( p->pPars->fVerbose )
Ssw_ManPrintStats( p );
if ( p->ppClasses )
Ssw_ClassesStop( p->ppClasses );
if ( p->pSml )
Ssw_SmlStop( p->pSml );
Vec_PtrFree( p->vFanins );
Vec_PtrFree( p->vUsedNodes );
Vec_PtrFree( p->vUsedPis );
Vec_IntFree( p->vSatVars );
Vec_PtrFree( p->vCommon );
FREE( p->pNodeToFrames );
FREE( p->pPatWords );
FREE( p->pPatWords2 );
free( p );
}
/**Function*************************************************************
Synopsis [Starts the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManStartSolver( Ssw_Man_t * p )
{
int Lit;
assert( p->pSat == NULL );
p->pSat = sat_solver_new();
sat_solver_setnvars( p->pSat, 1000 );
// var 0 is not used
// var 1 is reserved for const1 node - add the clause
p->nSatVars = 1;
Lit = toLit( p->nSatVars );
if ( p->pPars->fPolarFlip )
Lit = lit_neg( Lit );
sat_solver_addclause( p->pSat, &Lit, &Lit + 1 );
Ssw_ObjSetSatNum( p, Aig_ManConst1(p->pAig), p->nSatVars++ );
Vec_PtrClear( p->vUsedNodes );
Vec_PtrClear( p->vUsedPis );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswPairs.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [Calls to the SAT solver.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswPairs.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Reports the status of the miter.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_MiterStatus( Aig_Man_t * p, int fVerbose )
{
Aig_Obj_t * pObj, * pChild;
int i, CountConst0 = 0, CountNonConst0 = 0, CountUndecided = 0;
// if ( p->pData )
// return 0;
Saig_ManForEachPo( p, pObj, i )
{
pChild = Aig_ObjChild0(pObj);
// check if the output is constant 0
if ( pChild == Aig_ManConst0(p) )
{
CountConst0++;
continue;
}
// check if the output is constant 1
if ( pChild == Aig_ManConst1(p) )
{
CountNonConst0++;
continue;
}
// check if the output is a primary input
if ( p->nRegs == 0 && Aig_ObjIsPi(Aig_Regular(pChild)) )
{
CountNonConst0++;
continue;
}
// check if the output can be not constant 0
if ( Aig_Regular(pChild)->fPhase != (unsigned)Aig_IsComplement(pChild) )
{
CountNonConst0++;
continue;
}
CountUndecided++;
}
if ( fVerbose )
{
printf( "Miter has %d outputs. ", Saig_ManPoNum(p) );
printf( "Const0 = %d. ", CountConst0 );
printf( "NonConst0 = %d. ", CountNonConst0 );
printf( "Undecided = %d. ", CountUndecided );
printf( "\n" );
}
if ( CountNonConst0 )
return 0;
if ( CountUndecided )
return -1;
return 1;
}
/**Function*************************************************************
Synopsis [Transfer equivalent pairs to the miter.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Ssw_TransferSignalPairs( Aig_Man_t * pMiter, Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2 )
{
Vec_Int_t * vIds;
Aig_Obj_t * pObj1, * pObj2;
Aig_Obj_t * pObj1m, * pObj2m;
int i;
vIds = Vec_IntAlloc( 2 * Vec_IntSize(vIds1) );
for ( i = 0; i < Vec_IntSize(vIds1); i++ )
{
pObj1 = Aig_ManObj( pAig1, Vec_IntEntry(vIds1, i) );
pObj2 = Aig_ManObj( pAig2, Vec_IntEntry(vIds2, i) );
pObj1m = Aig_Regular(pObj1->pData);
pObj2m = Aig_Regular(pObj2->pData);
assert( pObj1m && pObj2m );
if ( pObj1m == pObj2m )
continue;
if ( pObj1m->Id < pObj2m->Id )
{
Vec_IntPush( vIds, pObj1m->Id );
Vec_IntPush( vIds, pObj2m->Id );
}
else
{
Vec_IntPush( vIds, pObj2m->Id );
Vec_IntPush( vIds, pObj1m->Id );
}
}
return vIds;
}
/**Function*************************************************************
Synopsis [Transform pairs into class representation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t ** Ssw_TransformPairsIntoTempClasses( Vec_Int_t * vPairs, int nObjNumMax )
{
Vec_Int_t ** pvClasses; // vector of classes
int * pReprs; // mapping nodes into their representatives
int Entry, idObj, idRepr, idReprObj, idReprRepr, i;
// allocate data-structures
pvClasses = CALLOC( Vec_Int_t *, nObjNumMax );
pReprs = ALLOC( int, nObjNumMax );
for ( i = 0; i < nObjNumMax; i++ )
pReprs[i] = -1;
// consider pairs
for ( i = 0; i < Vec_IntSize(vPairs); i += 2 )
{
// get both objects
idRepr = Vec_IntEntry( vPairs, i );
idObj = Vec_IntEntry( vPairs, i+1 );
assert( idObj > 0 );
assert( (pReprs[idRepr] == -1) || (pvClasses[pReprs[idRepr]] != NULL) );
assert( (pReprs[idObj] == -1) || (pvClasses[pReprs[idObj] ] != NULL) );
// get representatives of both objects
idReprRepr = pReprs[idRepr];
idReprObj = pReprs[idObj];
// check different situations
if ( idReprRepr == -1 && idReprObj == -1 )
{ // they do not have classes
// create a class
pvClasses[idRepr] = Vec_IntAlloc( 4 );
Vec_IntPush( pvClasses[idRepr], idRepr );
Vec_IntPush( pvClasses[idRepr], idObj );
pReprs[ idRepr ] = idRepr;
pReprs[ idObj ] = idRepr;
}
else if ( idReprRepr >= 0 && idReprObj == -1 )
{ // representative has a class
// add iObj to the same class
Vec_IntPushUniqueOrder( pvClasses[idReprRepr], idObj );
pReprs[ idObj ] = idReprRepr;
}
else if ( idReprRepr == -1 && idReprObj >= 0 )
{ // object has a class
assert( idReprObj != idRepr );
if ( idReprObj < idRepr )
{ // add idRepr to the same class
Vec_IntPushUniqueOrder( pvClasses[idReprObj], idRepr );
pReprs[ idRepr ] = idReprObj;
}
else // if ( idReprObj > idRepr )
{ // make idRepr new representative
Vec_IntPushFirst( pvClasses[idReprObj], idRepr );
pvClasses[idRepr] = pvClasses[idReprObj];
pvClasses[idReprObj] = NULL;
// set correct representatives of each node
Vec_IntForEachEntry( pvClasses[idRepr], Entry, i )
pReprs[ Entry ] = idRepr;
}
}
else // if ( idReprRepr >= 0 && idReprObj >= 0 )
{ // both have classes
if ( idReprRepr == idReprObj )
{ // the classes are the same
// nothing to do
}
else
{ // the classes are different
// find the repr of the new class
if ( idReprRepr < idReprObj )
{
Vec_IntForEachEntry( pvClasses[idReprObj], Entry, i )
{
Vec_IntPushUniqueOrder( pvClasses[idReprRepr], Entry );
pReprs[ Entry ] = idReprRepr;
}
Vec_IntFree( pvClasses[idReprObj] );
pvClasses[idReprObj] = NULL;
}
else // if ( idReprRepr > idReprObj )
{
Vec_IntForEachEntry( pvClasses[idReprRepr], Entry, i )
{
Vec_IntPushUniqueOrder( pvClasses[idReprObj], Entry );
pReprs[ Entry ] = idReprObj;
}
Vec_IntFree( pvClasses[idReprRepr] );
pvClasses[idReprRepr] = NULL;
}
}
}
}
free( pReprs );
return pvClasses;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_FreeTempClasses( Vec_Int_t ** pvClasses, int nObjNumMax )
{
int i;
for ( i = 0; i < nObjNumMax; i++ )
if ( pvClasses[i] )
Vec_IntFree( pvClasses[i] );
free( pvClasses );
}
/**Function*************************************************************
Synopsis [Performs signal correspondence for the miter of two AIGs with node pairs defined.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ssw_SignalCorrespondenceWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars )
{
Ssw_Man_t * p;
Aig_Man_t * pAigNew, * pMiter;
Ssw_Pars_t Pars;
Vec_Int_t * vPairs;
Vec_Int_t ** pvClasses;
assert( Vec_IntSize(vIds1) == Vec_IntSize(vIds2) );
// create sequential miter
pMiter = Saig_ManCreateMiter( pAig1, pAig2, 0 );
// transfer information to the miter
vPairs = Ssw_TransferSignalPairs( pMiter, pAig1, pAig2, vIds1, vIds2 );
// create representation of the classes
pvClasses = Ssw_TransformPairsIntoTempClasses( vPairs, Aig_ManObjNumMax(pMiter) );
Vec_IntFree( vPairs );
// if parameters are not given, create them
if ( pPars == NULL )
Ssw_ManSetDefaultParams( pPars = &Pars );
// start the induction manager
p = Ssw_ManCreate( pMiter, pPars );
// create equivalence classes using these IDs
p->ppClasses = Ssw_ClassesPreparePairs( pMiter, pvClasses );
p->pSml = Ssw_SmlStart( pMiter, 0, p->nFrames + p->pPars->nFramesAddSim, 1 );
Ssw_ClassesSetData( p->ppClasses, p->pSml, Ssw_SmlObjHashWord, Ssw_SmlObjIsConstWord, Ssw_SmlObjsAreEqualWord );
// perform refinement of classes
pAigNew = Ssw_SignalCorrespondenceRefine( p );
// cleanup
Ssw_FreeTempClasses( pvClasses, Aig_ManObjNumMax(pMiter) );
Ssw_ManStop( p );
Aig_ManStop( pMiter );
return pAigNew;
}
/**Function*************************************************************
Synopsis [Runs inductive SEC for the miter of two AIGs with node pairs defined.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ssw_SignalCorrespondeceTestPairs( Aig_Man_t * pAig )
{
Aig_Man_t * pAigNew, * pAigRes;
Ssw_Pars_t Pars, * pPars = &Pars;
Vec_Int_t * vIds1, * vIds2;
Aig_Obj_t * pObj, * pRepr;
int RetValue, i, clk = clock();
Ssw_ManSetDefaultParams( pPars );
pPars->fVerbose = 1;
pAigNew = Ssw_SignalCorrespondence( pAig, pPars );
// record pairs of equivalent nodes
vIds1 = Vec_IntAlloc( Aig_ManObjNumMax(pAig) );
vIds2 = Vec_IntAlloc( Aig_ManObjNumMax(pAig) );
Aig_ManForEachObj( pAig, pObj, i )
{
pRepr = Aig_Regular(pObj->pData);
if ( pRepr == NULL )
continue;
if ( Aig_ManObj(pAigNew, pRepr->Id) == NULL )
continue;
/*
if ( Aig_ObjIsNode(pObj) )
printf( "n " );
else if ( Saig_ObjIsPi(pAig, pObj) )
printf( "pi " );
else if ( Saig_ObjIsLo(pAig, pObj) )
printf( "lo " );
*/
Vec_IntPush( vIds1, Aig_ObjId(pObj) );
Vec_IntPush( vIds2, Aig_ObjId(pRepr) );
}
printf( "Recorded %d pairs (before: %d after: %d).\n", Vec_IntSize(vIds1), Aig_ManObjNumMax(pAig), Aig_ManObjNumMax(pAigNew) );
// try the new AIGs
pAigRes = Ssw_SignalCorrespondenceWithPairs( pAig, pAigNew, vIds1, vIds2, pPars );
Vec_IntFree( vIds1 );
Vec_IntFree( vIds2 );
// report the results
RetValue = Ssw_MiterStatus( pAigRes, 1 );
if ( RetValue == 1 )
printf( "Verification successful. " );
else if ( RetValue == 0 )
printf( "Verification failed with the counter-example. " );
else
printf( "Verification UNDECIDED. Remaining registers %d (total %d). ",
Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig) + Aig_ManRegNum(pAigNew) );
PRT( "Time", clock() - clk );
// cleanup
Aig_ManStop( pAigNew );
return pAigRes;
}
/**Function*************************************************************
Synopsis [Runs inductive SEC for the miter of two AIGs with node pairs defined.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SecWithPairs( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Vec_Int_t * vIds1, Vec_Int_t * vIds2, Ssw_Pars_t * pPars )
{
Aig_Man_t * pAigRes;
int RetValue, clk = clock();
assert( vIds1 != NULL && vIds2 != NULL );
// try the new AIGs
printf( "Performing specialized verification with node pairs.\n" );
pAigRes = Ssw_SignalCorrespondenceWithPairs( pAig1, pAig2, vIds1, vIds2, pPars );
// report the results
RetValue = Ssw_MiterStatus( pAigRes, 1 );
if ( RetValue == 1 )
printf( "Verification successful. " );
else if ( RetValue == 0 )
printf( "Verification failed with a counter-example. " );
else
printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d). ",
Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig1) + Aig_ManRegNum(pAig2) );
PRT( "Time", clock() - clk );
// cleanup
Aig_ManStop( pAigRes );
return RetValue;
}
/**Function*************************************************************
Synopsis [Runs inductive SEC for the miter of two AIGs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SecGeneral( Aig_Man_t * pAig1, Aig_Man_t * pAig2, Ssw_Pars_t * pPars )
{
Aig_Man_t * pAigRes, * pMiter;
int RetValue, clk = clock();
// try the new AIGs
printf( "Performing general verification without node pairs.\n" );
pMiter = Saig_ManCreateMiter( pAig1, pAig2, 0 );
pAigRes = Ssw_SignalCorrespondence( pMiter, pPars );
Aig_ManStop( pMiter );
// report the results
RetValue = Ssw_MiterStatus( pAigRes, 1 );
if ( RetValue == 1 )
printf( "Verification successful. " );
else if ( RetValue == 0 )
printf( "Verification failed with a counter-example. " );
else
printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d). ",
Aig_ManRegNum(pAigRes), Aig_ManRegNum(pAig1) + Aig_ManRegNum(pAig2) );
PRT( "Time", clock() - clk );
// cleanup
Aig_ManStop( pAigRes );
return RetValue;
}
/**Function*************************************************************
Synopsis [Runs inductive SEC for the miter of two AIGs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SecGeneralMiter( Aig_Man_t * pMiter, Ssw_Pars_t * pPars )
{
Aig_Man_t * pAigRes;
int RetValue, clk = clock();
// try the new AIGs
// printf( "Performing general verification without node pairs.\n" );
pAigRes = Ssw_SignalCorrespondence( pMiter, pPars );
// report the results
RetValue = Ssw_MiterStatus( pAigRes, 1 );
if ( RetValue == 1 )
printf( "Verification successful. " );
else if ( RetValue == 0 )
printf( "Verification failed with a counter-example. " );
else
printf( "Verification UNDECIDED. The number of remaining regs = %d (total = %d). ",
Aig_ManRegNum(pAigRes), Aig_ManRegNum(pMiter) );
PRT( "Time", clock() - clk );
// cleanup
Aig_ManStop( pAigRes );
return RetValue;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswPart.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [Partitioned signal correspondence.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswPart.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Performs partitioned sequential SAT sweepingG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Ssw_SignalCorrespondencePart( Aig_Man_t * pAig, Ssw_Pars_t * pPars )
{
int fPrintParts = 0;
char Buffer[100];
Aig_Man_t * pTemp, * pNew;
Vec_Ptr_t * vResult;
Vec_Int_t * vPart;
int * pMapBack;
int i, nCountPis, nCountRegs;
int nClasses, nPartSize, fVerbose;
int clk = clock();
// save parameters
nPartSize = pPars->nPartSize; pPars->nPartSize = 0;
fVerbose = pPars->fVerbose; pPars->fVerbose = 0;
// generate partitions
if ( pAig->vClockDoms )
{
// divide large clock domains into separate partitions
vResult = Vec_PtrAlloc( 100 );
Vec_PtrForEachEntry( (Vec_Ptr_t *)pAig->vClockDoms, vPart, i )
{
if ( nPartSize && Vec_IntSize(vPart) > nPartSize )
Aig_ManPartDivide( vResult, vPart, nPartSize, pPars->nOverSize );
else
Vec_PtrPush( vResult, Vec_IntDup(vPart) );
}
}
else
vResult = Aig_ManRegPartitionSimple( pAig, nPartSize, pPars->nOverSize );
// vResult = Aig_ManPartitionSmartRegisters( pAig, nPartSize, 0 );
// vResult = Aig_ManRegPartitionSmart( pAig, nPartSize );
if ( fPrintParts )
{
// print partitions
printf( "Simple partitioning. %d partitions are saved:\n", Vec_PtrSize(vResult) );
Vec_PtrForEachEntry( vResult, vPart, i )
{
extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact );
sprintf( Buffer, "part%03d.aig", i );
pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, NULL );
Ioa_WriteAiger( pTemp, Buffer, 0, 0 );
printf( "part%03d.aig : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d.\n",
i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp) );
Aig_ManStop( pTemp );
}
}
// perform SSW with partitions
Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
Vec_PtrForEachEntry( vResult, vPart, i )
{
pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack );
Aig_ManSetRegNum( pTemp, pTemp->nRegs );
// create the projection of 1-hot registers
if ( pAig->vOnehots )
pTemp->vOnehots = Aig_ManRegProjectOnehots( pAig, pTemp, pAig->vOnehots, fVerbose );
// run SSW
pNew = Ssw_SignalCorrespondence( pTemp, pPars );
nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack );
if ( fVerbose )
printf( "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n",
i, Vec_IntSize(vPart), Aig_ManPiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), pPars->nIters, nClasses );
Aig_ManStop( pNew );
Aig_ManStop( pTemp );
free( pMapBack );
}
// remap the AIG
pNew = Aig_ManDupRepr( pAig, 0 );
Aig_ManSeqCleanup( pNew );
// Aig_ManPrintStats( pAig );
// Aig_ManPrintStats( pNew );
Vec_VecFree( (Vec_Vec_t *)vResult );
pPars->nPartSize = nPartSize;
pPars->fVerbose = fVerbose;
if ( fVerbose )
{
PRT( "Total time", clock() - clk );
}
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswSat.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [Calls to the SAT solver.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Runs equivalence test for the two nodes.]
Description [Both nodes should be regular and different from each other.]
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_NodesAreEquiv( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
{
int nBTLimit = p->pPars->nBTLimit;
int pLits[3], nLits, RetValue, RetValue1, clk;//, status;
p->nSatCalls++;
// sanity checks
assert( !Aig_IsComplement(pOld) );
assert( !Aig_IsComplement(pNew) );
assert( pOld != pNew );
if ( p->pSat == NULL )
Ssw_ManStartSolver( p );
// if the nodes do not have SAT variables, allocate them
Ssw_CnfNodeAddToSolver( p, pOld );
Ssw_CnfNodeAddToSolver( p, pNew );
if ( p->pSat->qtail != p->pSat->qhead )
{
RetValue = sat_solver_simplify(p->pSat);
assert( RetValue != 0 );
}
// solve under assumptions
// A = 1; B = 0 OR A = 1; B = 1
nLits = 2;
pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 0 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), pOld->fPhase == pNew->fPhase );
if ( p->iOutputLit > -1 )
pLits[nLits++] = p->iOutputLit;
if ( p->pPars->fPolarFlip )
{
if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
}
//Sat_SolverWriteDimacs( p->pSat, "temp.cnf", pLits, pLits + 2, 1 );
clk = clock();
RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + nLits,
(sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
p->timeSat += clock() - clk;
if ( RetValue1 == l_False )
{
p->timeSatUnsat += clock() - clk;
if ( nLits == 2 )
{
pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
assert( RetValue );
}
p->nSatCallsUnsat++;
}
else if ( RetValue1 == l_True )
{
p->timeSatSat += clock() - clk;
p->nSatCallsSat++;
return 0;
}
else // if ( RetValue1 == l_Undef )
{
p->timeSatUndec += clock() - clk;
p->nSatFailsReal++;
return -1;
}
// if the old node was constant 0, we already know the answer
if ( pOld == Aig_ManConst1(p->pFrames) )
{
p->nSatProof++;
return 1;
}
// solve under assumptions
// A = 0; B = 1 OR A = 0; B = 0
nLits = 2;
pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 1 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), pOld->fPhase ^ pNew->fPhase );
if ( p->iOutputLit > -1 )
pLits[nLits++] = p->iOutputLit;
if ( p->pPars->fPolarFlip )
{
if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
}
/*
if ( p->pSat->qtail != p->pSat->qhead )
{
RetValue = sat_solver_simplify(p->pSat);
assert( RetValue != 0 );
}
*/
clk = clock();
RetValue1 = sat_solver_solve( p->pSat, pLits, pLits + nLits,
(sint64)nBTLimit, (sint64)0, (sint64)0, (sint64)0 );
p->timeSat += clock() - clk;
if ( RetValue1 == l_False )
{
p->timeSatUnsat += clock() - clk;
if ( nLits == 2 )
{
pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
assert( RetValue );
}
p->nSatCallsUnsat++;
}
else if ( RetValue1 == l_True )
{
p->timeSatSat += clock() - clk;
p->nSatCallsSat++;
return 0;
}
else // if ( RetValue1 == l_Undef )
{
p->timeSatUndec += clock() - clk;
p->nSatFailsReal++;
return -1;
}
// return SAT proof
p->nSatProof++;
return 1;
}
/**Function*************************************************************
Synopsis [Constrains two nodes to be equivalent in the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_NodesAreConstrained( Ssw_Man_t * p, Aig_Obj_t * pOld, Aig_Obj_t * pNew )
{
int pLits[2], RetValue, fComplNew;
Aig_Obj_t * pTemp;
// sanity checks
assert( Aig_Regular(pOld) != Aig_Regular(pNew) );
// move constant to the old node
if ( Aig_Regular(pNew) == Aig_ManConst1(p->pFrames) )
{
assert( Aig_Regular(pOld) != Aig_ManConst1(p->pFrames) );
pTemp = pOld;
pOld = pNew;
pNew = pTemp;
}
// move complement to the new node
if ( Aig_IsComplement(pOld) )
{
pOld = Aig_Regular(pOld);
pNew = Aig_Not(pNew);
}
// start the solver
if ( p->pSat == NULL )
Ssw_ManStartSolver( p );
// if the nodes do not have SAT variables, allocate them
Ssw_CnfNodeAddToSolver( p, pOld );
Ssw_CnfNodeAddToSolver( p, Aig_Regular(pNew) );
// transform the new node
fComplNew = Aig_IsComplement( pNew );
pNew = Aig_Regular( pNew );
// consider the constant 1 case
if ( pOld == Aig_ManConst1(p->pFrames) )
{
// add constaint A = 1 ----> A
pLits[0] = toLitCond( Ssw_ObjSatNum(p,pNew), fComplNew );
if ( p->pPars->fPolarFlip )
{
if ( pNew->fPhase ) pLits[0] = lit_neg( pLits[0] );
}
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 );
assert( RetValue );
}
else
{
// add constaint A = B ----> (A v !B)(!A v B)
// (A v !B)
pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 0 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), !fComplNew );
if ( p->pPars->fPolarFlip )
{
if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
}
pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
assert( RetValue );
// (!A v B)
pLits[0] = toLitCond( Ssw_ObjSatNum(p,pOld), 1 );
pLits[1] = toLitCond( Ssw_ObjSatNum(p,pNew), fComplNew);
if ( p->pPars->fPolarFlip )
{
if ( pOld->fPhase ) pLits[0] = lit_neg( pLits[0] );
if ( pNew->fPhase ) pLits[1] = lit_neg( pLits[1] );
}
pLits[0] = lit_neg( pLits[0] );
pLits[1] = lit_neg( pLits[1] );
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 2 );
assert( RetValue );
}
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswSim.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [Sequential simulator used by the inductive prover.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswSim.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
// simulation manager
struct Ssw_Sml_t_
{
Aig_Man_t * pAig; // the original AIG manager
int nPref; // the number of timeframes in the prefix
int nFrames; // the number of timeframes
int nWordsFrame; // the number of words in each timeframe
int nWordsTotal; // the total number of words at a node
int nWordsPref; // the number of word in the prefix
int fNonConstOut; // have seen a non-const-0 output during simulation
int nSimRounds; // statistics
int timeSim; // statistics
unsigned pData[0]; // simulation data for the nodes
};
static inline unsigned * Ssw_ObjSim( Ssw_Sml_t * p, int Id ) { return p->pData + p->nWordsTotal * Id; }
static inline unsigned Ssw_ObjRandomSim() { return Aig_ManRandom(0); }
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Computes hash value of the node using its simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned Ssw_SmlObjHashWord( Ssw_Sml_t * p, Aig_Obj_t * pObj )
{
static int s_SPrimes[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;
assert( p->nWordsTotal <= 128 );
uHash = 0;
pSims = Ssw_ObjSim(p, pObj->Id);
for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
uHash ^= pSims[i] * s_SPrimes[i & 0x7F];
return uHash;
}
/**Function*************************************************************
Synopsis [Returns 1 if simulation info is composed of all zeros.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlObjIsConstWord( Ssw_Sml_t * p, Aig_Obj_t * pObj )
{
unsigned * pSims;
int i;
pSims = Ssw_ObjSim(p, pObj->Id);
for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
if ( pSims[i] )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Returns 1 if simulation infos are equal.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlObjsAreEqualWord( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
{
unsigned * pSims0, * pSims1;
int i;
pSims0 = Ssw_ObjSim(p, pObj0->Id);
pSims1 = Ssw_ObjSim(p, pObj1->Id);
for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
if ( pSims0[i] != pSims1[i] )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Returns 1 if the node appears to be constant 1 candidate.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlObjIsConstBit( void * p, Aig_Obj_t * pObj )
{
return pObj->fPhase == pObj->fMarkB;
}
/**Function*************************************************************
Synopsis [Returns 1 if the nodes appear equal.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlObjsAreEqualBit( void * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1 )
{
return (pObj0->fPhase == pObj1->fPhase) == (pObj0->fMarkB == pObj1->fMarkB);
}
/**Function*************************************************************
Synopsis [Counts the number of 1s in the XOR of simulation data.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlNodeNotEquWeight( Ssw_Sml_t * p, int Left, int Right )
{
unsigned * pSimL, * pSimR;
int k, Counter = 0;
pSimL = Ssw_ObjSim( p, Left );
pSimR = Ssw_ObjSim( p, Right );
for ( k = p->nWordsPref; k < p->nWordsTotal; k++ )
Counter += Aig_WordCountOnes( pSimL[k] ^ pSimR[k] );
return Counter;
}
/**Function*************************************************************
Synopsis [Returns 1 if simulation info is composed of all zeros.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlNodeIsZero( Ssw_Sml_t * p, Aig_Obj_t * pObj )
{
unsigned * pSims;
int i;
pSims = Ssw_ObjSim(p, pObj->Id);
for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
if ( pSims[i] )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Counts the number of one's in the patten of the output.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlNodeCountOnes( Ssw_Sml_t * p, Aig_Obj_t * pObj )
{
unsigned * pSims;
int i, Counter = 0;
pSims = Ssw_ObjSim(p, pObj->Id);
for ( i = 0; i < p->nWordsTotal; i++ )
Counter += Aig_WordCountOnes( pSims[i] );
return Counter;
}
/**Function*************************************************************
Synopsis [Generated const 0 pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlSavePattern0( Ssw_Man_t * p, int fInit )
{
memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
}
/**Function*************************************************************
Synopsis [[Generated const 1 pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlSavePattern1( Ssw_Man_t * p, int fInit )
{
Aig_Obj_t * pObj;
int i, k, nTruePis;
memset( p->pPatWords, 0xff, sizeof(unsigned) * p->nPatWords );
if ( !fInit )
return;
// clear the state bits to correspond to all-0 initial state
nTruePis = Saig_ManPiNum(p->pAig);
k = 0;
Saig_ManForEachLo( p->pAig, pObj, i )
Aig_InfoXorBit( p->pPatWords, nTruePis * p->nFrames + k++ );
}
/**Function*************************************************************
Synopsis [Copy pattern from the solver into the internal storage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlSavePattern( Ssw_Man_t * p )
{
Aig_Obj_t * pObj;
int i;
memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
Aig_ManForEachPi( p->pFrames, pObj, i )
if ( p->pSat->model.ptr[Ssw_ObjSatNum(p, pObj)] == l_True )
Aig_InfoSetBit( p->pPatWords, i );
/*
if ( p->vCex )
{
Vec_IntClear( p->vCex );
for ( i = 0; i < Saig_ManPiNum(p->pAig); i++ )
Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) );
for ( i = Saig_ManPiNum(p->pFrames); i < Aig_ManPiNum(p->pFrames); i++ )
Vec_IntPush( p->vCex, Aig_InfoHasBit( p->pPatWords, i ) );
}
*/
/*
printf( "Pattern: " );
Aig_ManForEachPi( p->pFrames, pObj, i )
printf( "%d", Aig_InfoHasBit( p->pPatWords, i ) );
printf( "\n" );
*/
}
/**Function*************************************************************
Synopsis [Creates the counter-example from the successful pattern.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int * Ssw_SmlCheckOutputSavePattern( Ssw_Sml_t * p, Aig_Obj_t * pObjPo )
{
Aig_Obj_t * pFanin, * pObjPi;
unsigned * pSims;
int i, k, BestPat, * pModel;
// find the word of the pattern
pFanin = Aig_ObjFanin0(pObjPo);
pSims = Ssw_ObjSim(p, pFanin->Id);
for ( i = 0; i < p->nWordsTotal; i++ )
if ( pSims[i] )
break;
assert( i < p->nWordsTotal );
// 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->pAig)+1 );
Aig_ManForEachPi( p->pAig, pObjPi, i )
{
pModel[i] = Aig_InfoHasBit(Ssw_ObjSim(p, pObjPi->Id), BestPat);
// printf( "%d", pModel[i] );
}
pModel[Aig_ManPiNum(p->pAig)] = pObjPo->Id;
// printf( "\n" );
return pModel;
}
/**Function*************************************************************
Synopsis [Returns 1 if the one of the output is already non-constant 0.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int * Ssw_SmlCheckOutput( Ssw_Sml_t * p )
{
Aig_Obj_t * pObj;
int i;
// make sure the reference simulation pattern does not detect the bug
pObj = Aig_ManPo( p->pAig, 0 );
assert( Aig_ObjFanin0(pObj)->fPhase == (unsigned)Aig_ObjFaninC0(pObj) );
Aig_ManForEachPo( p->pAig, pObj, i )
{
if ( !Ssw_SmlObjIsConstWord( p, Aig_ObjFanin0(pObj) ) )
{
// create the counter-example from this pattern
return Ssw_SmlCheckOutputSavePattern( p, pObj );
}
}
return NULL;
}
/**Function*************************************************************
Synopsis [Assigns random patterns to the PI node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlAssignRandom( Ssw_Sml_t * p, Aig_Obj_t * pObj )
{
unsigned * pSims;
int i;
assert( Aig_ObjIsPi(pObj) );
pSims = Ssw_ObjSim( p, pObj->Id );
for ( i = 0; i < p->nWordsTotal; i++ )
pSims[i] = Ssw_ObjRandomSim();
}
/**Function*************************************************************
Synopsis [Assigns random patterns to the PI node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlAssignRandomFrame( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
{
unsigned * pSims;
int i;
assert( Aig_ObjIsPi(pObj) );
pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = Ssw_ObjRandomSim();
}
/**Function*************************************************************
Synopsis [Assigns constant patterns to the PI node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlObjAssignConst( Ssw_Sml_t * p, Aig_Obj_t * pObj, int fConst1, int iFrame )
{
unsigned * pSims;
int i;
assert( Aig_ObjIsPi(pObj) );
pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = fConst1? ~(unsigned)0 : 0;
}
/**Function*************************************************************
Synopsis [Assigns constant patterns to the PI node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
unsigned Ssw_SmlObjGetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iWord, int iFrame )
{
unsigned * pSims;
// assert( Aig_ObjIsPi(pObj) );
pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
return pSims[iWord];
}
/**Function*************************************************************
Synopsis [Assigns constant patterns to the PI node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlObjSetWord( Ssw_Sml_t * p, Aig_Obj_t * pObj, unsigned Word, int iWord, int iFrame )
{
unsigned * pSims;
assert( Aig_ObjIsPi(pObj) );
pSims = Ssw_ObjSim( p, pObj->Id ) + p->nWordsFrame * iFrame;
pSims[iWord] = Word;
}
/**Function*************************************************************
Synopsis [Assings random simulation info for the PIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlInitialize( Ssw_Sml_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
Saig_ManForEachPi( p->pAig, pObj, i )
Ssw_SmlAssignRandom( p, pObj );
// assign the initial state for the latches
Saig_ManForEachLo( p->pAig, pObj, i )
Ssw_SmlObjAssignConst( p, pObj, 0, 0 );
}
else
{
Aig_ManForEachPi( p->pAig, pObj, i )
Ssw_SmlAssignRandom( p, pObj );
}
}
/**Function*************************************************************
Synopsis [Assings distance-1 simulation info for the PIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlAssignDist1( Ssw_Sml_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 )
Ssw_SmlObjAssignConst( 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( Ssw_ObjSim( p, Aig_ManPi(p->pAig,i)->Id ), i+1 );
}
else
{
int fUseDist1 = 0;
// copy the PI info for each frame
nTruePis = Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig);
for ( f = 0; f < p->nFrames; f++ )
Saig_ManForEachPi( p->pAig, pObj, i )
Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * f + i), f );
// copy the latch info
k = 0;
Saig_ManForEachLo( p->pAig, pObj, i )
Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, nTruePis * p->nFrames + k++), 0 );
// assert( p->pFrames == NULL || nTruePis * p->nFrames + k == Aig_ManPiNum(p->pFrames) );
// flip one bit of the last frame
if ( fUseDist1 ) //&& p->nFrames == 2 )
{
Limit = AIG_MIN( nTruePis, p->nWordsFrame * 32 - 1 );
for ( i = 0; i < Limit; i++ )
Aig_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig, i)->Id ) + p->nWordsFrame*(p->nFrames-1), i+1 );
}
}
}
/**Function*************************************************************
Synopsis [Assings distance-1 simulation info for the PIs.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlAssignDist1Plus( Ssw_Sml_t * p, unsigned * pPat )
{
Aig_Obj_t * pObj;
int f, i, Limit;
assert( p->nFrames > 0 );
// copy the pattern into the primary inputs
Aig_ManForEachPi( p->pAig, pObj, i )
Ssw_SmlObjAssignConst( p, pObj, Aig_InfoHasBit(pPat, i), 0 );
/*
// set distance one PIs for the first frame
Limit = AIG_MIN( Saig_ManPiNum(p->pAig), p->nWordsFrame * 32 - 1 );
for ( i = 0; i < Limit; i++ )
Aig_InfoXorBit( Ssw_ObjSim( p, Aig_ManPi(p->pAig, i)->Id ), i+1 );
*/
// create random info for the remaining timeframes
for ( f = 1; f < p->nFrames; f++ )
Saig_ManForEachPi( p->pAig, pObj, i )
Ssw_SmlAssignRandomFrame( p, pObj, f );
}
/**Function*************************************************************
Synopsis [Simulates one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlNodeSimulate( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
{
unsigned * pSims, * pSims0, * pSims1;
int fCompl, fCompl0, fCompl1, i;
assert( !Aig_IsComplement(pObj) );
assert( Aig_ObjIsNode(pObj) );
assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
// get hold of the simulation information
pSims = Ssw_ObjSim(p, pObj->Id) + p->nWordsFrame * iFrame;
pSims0 = Ssw_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + p->nWordsFrame * iFrame;
pSims1 = Ssw_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*************************************************************
Synopsis [Simulates one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlNodesCompareInFrame( Ssw_Sml_t * p, Aig_Obj_t * pObj0, Aig_Obj_t * pObj1, int iFrame0, int iFrame1 )
{
unsigned * pSims0, * pSims1;
int i;
assert( !Aig_IsComplement(pObj0) );
assert( !Aig_IsComplement(pObj1) );
assert( iFrame0 == 0 || p->nWordsFrame < p->nWordsTotal );
assert( iFrame1 == 0 || p->nWordsFrame < p->nWordsTotal );
// get hold of the simulation information
pSims0 = Ssw_ObjSim(p, pObj0->Id) + p->nWordsFrame * iFrame0;
pSims1 = Ssw_ObjSim(p, pObj1->Id) + p->nWordsFrame * iFrame1;
// compare
for ( i = 0; i < p->nWordsFrame; i++ )
if ( pSims0[i] != pSims1[i] )
return 0;
return 1;
}
/**Function*************************************************************
Synopsis [Simulates one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlNodeCopyFanin( Ssw_Sml_t * p, Aig_Obj_t * pObj, int iFrame )
{
unsigned * pSims, * pSims0;
int fCompl, fCompl0, i;
assert( !Aig_IsComplement(pObj) );
assert( Aig_ObjIsPo(pObj) );
assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
// get hold of the simulation information
pSims = Ssw_ObjSim(p, pObj->Id) + p->nWordsFrame * iFrame;
pSims0 = Ssw_ObjSim(p, Aig_ObjFanin0(pObj)->Id) + p->nWordsFrame * 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 < p->nWordsFrame; i++ )
pSims[i] = ~pSims0[i];
else
for ( i = 0; i < p->nWordsFrame; i++ )
pSims[i] = pSims0[i];
}
/**Function*************************************************************
Synopsis [Simulates one node.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlNodeTransferNext( Ssw_Sml_t * p, Aig_Obj_t * pOut, Aig_Obj_t * pIn, int iFrame )
{
unsigned * pSims0, * pSims1;
int i;
assert( !Aig_IsComplement(pOut) );
assert( !Aig_IsComplement(pIn) );
assert( Aig_ObjIsPo(pOut) );
assert( Aig_ObjIsPi(pIn) );
assert( iFrame == 0 || p->nWordsFrame < p->nWordsTotal );
// get hold of the simulation information
pSims0 = Ssw_ObjSim(p, pOut->Id) + p->nWordsFrame * iFrame;
pSims1 = Ssw_ObjSim(p, pIn->Id) + p->nWordsFrame * (iFrame+1);
// copy information as it is
for ( i = 0; i < p->nWordsFrame; i++ )
pSims1[i] = pSims0[i];
}
/**Function*************************************************************
Synopsis [Check if any of the POs becomes non-constant.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlCheckNonConstOutputs( Ssw_Sml_t * p )
{
Aig_Obj_t * pObj;
int i;
Saig_ManForEachPo( p->pAig, pObj, i )
if ( !Ssw_SmlNodeIsZero(p, pObj) )
return 1;
return 0;
}
/**Function*************************************************************
Synopsis [Simulates AIG manager.]
Description [Assumes that the PI simulation info is attached.]
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlSimulateOne( Ssw_Sml_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 )
Ssw_SmlNodeSimulate( p, pObj, f );
// copy simulation info into outputs
Saig_ManForEachPo( p->pAig, pObj, i )
Ssw_SmlNodeCopyFanin( p, pObj, f );
// quit if this is the last timeframe
if ( f == p->nFrames - 1 )
break;
// copy simulation info into outputs
Saig_ManForEachLi( p->pAig, pObj, i )
Ssw_SmlNodeCopyFanin( p, pObj, f );
// copy simulation info into the inputs
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
Ssw_SmlNodeTransferNext( p, pObjLi, pObjLo, f );
}
p->timeSim += clock() - clk;
p->nSimRounds++;
}
/**Function*************************************************************
Synopsis [Simulates AIG manager.]
Description [Assumes that the PI simulation info is attached.]
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlSimulateOneFrame( Ssw_Sml_t * p )
{
Aig_Obj_t * pObj, * pObjLi, * pObjLo;
int i, clk;
clk = clock();
// simulate the nodes
Aig_ManForEachNode( p->pAig, pObj, i )
Ssw_SmlNodeSimulate( p, pObj, 0 );
// copy simulation info into outputs
Saig_ManForEachLi( p->pAig, pObj, i )
Ssw_SmlNodeCopyFanin( p, pObj, 0 );
// copy simulation info into the inputs
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
Ssw_SmlNodeTransferNext( p, pObjLi, pObjLo, 0 );
p->timeSim += clock() - clk;
p->nSimRounds++;
}
/**Function*************************************************************
Synopsis [Allocates simulation manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Sml_t * Ssw_SmlStart( Aig_Man_t * pAig, int nPref, int nFrames, int nWordsFrame )
{
Ssw_Sml_t * p;
p = (Ssw_Sml_t *)malloc( sizeof(Ssw_Sml_t) + sizeof(unsigned) * Aig_ManObjNumMax(pAig) * (nPref + nFrames) * nWordsFrame );
memset( p, 0, sizeof(Ssw_Sml_t) + sizeof(unsigned) * (nPref + nFrames) * nWordsFrame );
p->pAig = pAig;
p->nPref = nPref;
p->nFrames = nPref + nFrames;
p->nWordsFrame = nWordsFrame;
p->nWordsTotal = (nPref + nFrames) * nWordsFrame;
p->nWordsPref = nPref * nWordsFrame;
return p;
}
/**Function*************************************************************
Synopsis [Allocates simulation manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlClean( Ssw_Sml_t * p )
{
memset( p->pData, 0, sizeof(unsigned) * Aig_ManObjNumMax(p->pAig) * p->nWordsTotal );
}
/**Function*************************************************************
Synopsis [Deallocates simulation manager.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlStop( Ssw_Sml_t * p )
{
free( p );
}
/**Function*************************************************************
Synopsis [Performs simulation of the uninitialized circuit.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Sml_t * Ssw_SmlSimulateComb( Aig_Man_t * pAig, int nWords )
{
Ssw_Sml_t * p;
p = Ssw_SmlStart( pAig, 0, 1, nWords );
Ssw_SmlInitialize( p, 0 );
Ssw_SmlSimulateOne( p );
return p;
}
/**Function*************************************************************
Synopsis [Performs simulation of the initialized circuit.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Sml_t * Ssw_SmlSimulateSeq( Aig_Man_t * pAig, int nPref, int nFrames, int nWords )
{
Ssw_Sml_t * p;
p = Ssw_SmlStart( pAig, nPref, nFrames, nWords );
Ssw_SmlInitialize( p, 1 );
Ssw_SmlSimulateOne( p );
p->fNonConstOut = Ssw_SmlCheckNonConstOutputs( p );
return p;
}
/**Function*************************************************************
Synopsis [Allocates a counter-example.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Cex_t * Ssw_SmlAllocCounterExample( int nRegs, int nRealPis, int nFrames )
{
Ssw_Cex_t * pCex;
int nWords = Aig_BitWordNum( nRegs + nRealPis * nFrames );
pCex = (Ssw_Cex_t *)malloc( sizeof(Ssw_Cex_t) + sizeof(unsigned) * nWords );
memset( pCex, 0, sizeof(Ssw_Cex_t) + sizeof(unsigned) * nWords );
pCex->nRegs = nRegs;
pCex->nPis = nRealPis;
pCex->nBits = nRegs + nRealPis * nFrames;
return pCex;
}
/**Function*************************************************************
Synopsis [Frees the counter-example.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlFreeCounterExample( Ssw_Cex_t * pCex )
{
free( pCex );
}
/**Function*************************************************************
Synopsis [Resimulates the counter-example.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlRunCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p )
{
Ssw_Sml_t * pSml;
Aig_Obj_t * pObj;
int RetValue, i, k, iBit;
assert( Aig_ManRegNum(pAig) > 0 );
assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) );
// start a new sequential simulator
pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 );
// assign simulation info for the registers
iBit = 0;
Saig_ManForEachLo( pAig, pObj, i )
Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 );
// assign simulation info for the primary inputs
for ( i = 0; i <= p->iFrame; i++ )
Saig_ManForEachPi( pAig, pObj, k )
Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i );
assert( iBit == p->nBits );
// run random simulation
Ssw_SmlSimulateOne( pSml );
// check if the given output has failed
RetValue = !Ssw_SmlNodeIsZero( pSml, Aig_ManPo(pAig, p->iPo) );
Ssw_SmlStop( pSml );
return RetValue;
}
/**Function*************************************************************
Synopsis [Resimulates the counter-example.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlFindOutputCounterExample( Aig_Man_t * pAig, Ssw_Cex_t * p )
{
Ssw_Sml_t * pSml;
Aig_Obj_t * pObj;
int i, k, iBit, iOut;
assert( Aig_ManRegNum(pAig) > 0 );
assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) );
// start a new sequential simulator
pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 );
// assign simulation info for the registers
iBit = 0;
Saig_ManForEachLo( pAig, pObj, i )
Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 );
// assign simulation info for the primary inputs
for ( i = 0; i <= p->iFrame; i++ )
Saig_ManForEachPi( pAig, pObj, k )
Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i );
assert( iBit == p->nBits );
// run random simulation
Ssw_SmlSimulateOne( pSml );
// check if the given output has failed
iOut = -1;
Saig_ManForEachPo( pAig, pObj, k )
if ( !Ssw_SmlNodeIsZero( pSml, Aig_ManPo(pAig, k) ) )
{
iOut = k;
break;
}
Ssw_SmlStop( pSml );
return iOut;
}
/**Function*************************************************************
Synopsis [Creates sequential counter-example from the simulation info.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Cex_t * Ssw_SmlGetCounterExample( Ssw_Sml_t * p )
{
Ssw_Cex_t * pCex;
Aig_Obj_t * pObj;
unsigned * pSims;
int iPo, iFrame, iBit, i, k;
// make sure the simulation manager has it
assert( p->fNonConstOut );
// find the first output that failed
iPo = -1;
iBit = -1;
iFrame = -1;
Saig_ManForEachPo( p->pAig, pObj, iPo )
{
if ( Ssw_SmlNodeIsZero(p, pObj) )
continue;
pSims = Ssw_ObjSim( p, pObj->Id );
for ( i = p->nWordsPref; i < p->nWordsTotal; i++ )
if ( pSims[i] )
{
iFrame = i / p->nWordsFrame;
iBit = 32 * (i % p->nWordsFrame) + Aig_WordFindFirstBit( pSims[i] );
break;
}
break;
}
assert( iPo < Aig_ManPoNum(p->pAig)-Aig_ManRegNum(p->pAig) );
assert( iFrame < p->nFrames );
assert( iBit < 32 * p->nWordsFrame );
// allocate the counter example
pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(p->pAig), Aig_ManPiNum(p->pAig) - Aig_ManRegNum(p->pAig), iFrame + 1 );
pCex->iPo = iPo;
pCex->iFrame = iFrame;
// copy the bit data
Saig_ManForEachLo( p->pAig, pObj, k )
{
pSims = Ssw_ObjSim( p, pObj->Id );
if ( Aig_InfoHasBit( pSims, iBit ) )
Aig_InfoSetBit( pCex->pData, k );
}
for ( i = 0; i <= iFrame; i++ )
{
Saig_ManForEachPi( p->pAig, pObj, k )
{
pSims = Ssw_ObjSim( p, pObj->Id );
if ( Aig_InfoHasBit( pSims, 32 * p->nWordsFrame * i + iBit ) )
Aig_InfoSetBit( pCex->pData, pCex->nRegs + pCex->nPis * i + k );
}
}
// verify the counter example
if ( !Ssw_SmlRunCounterExample( p->pAig, pCex ) )
{
printf( "Ssw_SmlGetCounterExample(): Counter-example is invalid.\n" );
Ssw_SmlFreeCounterExample( pCex );
pCex = NULL;
}
return pCex;
}
/**Function*************************************************************
Synopsis [Generates seq counter-example from the combinational one.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Cex_t * Ssw_SmlCopyCounterExample( Aig_Man_t * pAig, Aig_Man_t * pFrames, int * pModel )
{
Ssw_Cex_t * pCex;
Aig_Obj_t * pObj;
int i, nFrames, nTruePis, nTruePos, iPo, iFrame;
// get the number of frames
assert( Aig_ManRegNum(pAig) > 0 );
assert( Aig_ManRegNum(pFrames) == 0 );
nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig);
nTruePos = Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig);
nFrames = Aig_ManPiNum(pFrames) / nTruePis;
assert( nTruePis * nFrames == Aig_ManPiNum(pFrames) );
assert( nTruePos * nFrames == Aig_ManPoNum(pFrames) );
// find the PO that failed
iPo = -1;
iFrame = -1;
Aig_ManForEachPo( pFrames, pObj, i )
if ( pObj->Id == pModel[Aig_ManPiNum(pFrames)] )
{
iPo = i % nTruePos;
iFrame = i / nTruePos;
break;
}
assert( iPo >= 0 );
// allocate the counter example
pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 );
pCex->iPo = iPo;
pCex->iFrame = iFrame;
// copy the bit data
for ( i = 0; i < Aig_ManPiNum(pFrames); i++ )
{
if ( pModel[i] )
Aig_InfoSetBit( pCex->pData, pCex->nRegs + i );
if ( pCex->nRegs + i == pCex->nBits - 1 )
break;
}
// verify the counter example
if ( !Ssw_SmlRunCounterExample( pAig, pCex ) )
{
printf( "Ssw_SmlGetCounterExample(): Counter-example is invalid.\n" );
Ssw_SmlFreeCounterExample( pCex );
pCex = NULL;
}
return pCex;
}
/**Function*************************************************************
Synopsis [Make the trivial counter-example for the trivially asserted output.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Cex_t * Ssw_SmlTrivCounterExample( Aig_Man_t * pAig, int iFrameOut )
{
Ssw_Cex_t * pCex;
int nTruePis, nTruePos, iPo, iFrame;
assert( Aig_ManRegNum(pAig) > 0 );
nTruePis = Aig_ManPiNum(pAig)-Aig_ManRegNum(pAig);
nTruePos = Aig_ManPoNum(pAig)-Aig_ManRegNum(pAig);
iPo = iFrameOut % nTruePos;
iFrame = iFrameOut / nTruePos;
// allocate the counter example
pCex = Ssw_SmlAllocCounterExample( Aig_ManRegNum(pAig), nTruePis, iFrame + 1 );
pCex->iPo = iPo;
pCex->iFrame = iFrame;
return pCex;
}
/**Function*************************************************************
Synopsis [Make the trivial counter-example for the trivially asserted output.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Ssw_Cex_t * Ssw_SmlDupCounterExample( Ssw_Cex_t * p, int nRegsNew )
{
Ssw_Cex_t * pCex;
int i;
pCex = Ssw_SmlAllocCounterExample( nRegsNew, p->nPis, p->iFrame+1 );
pCex->iPo = p->iPo;
pCex->iFrame = p->iFrame;
for ( i = p->nRegs; i < p->nBits; i++ )
if ( Aig_InfoHasBit(p->pData, i) )
Aig_InfoSetBit( pCex->pData, pCex->nRegs + i - p->nRegs );
return pCex;
}
/**Function*************************************************************
Synopsis [Resimulates the counter-example.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_SmlWriteCounterExample( FILE * pFile, Aig_Man_t * pAig, Ssw_Cex_t * p )
{
Ssw_Sml_t * pSml;
Aig_Obj_t * pObj;
int RetValue, i, k, iBit;
unsigned * pSims;
assert( Aig_ManRegNum(pAig) > 0 );
assert( Aig_ManRegNum(pAig) < Aig_ManPiNum(pAig) );
// start a new sequential simulator
pSml = Ssw_SmlStart( pAig, 0, p->iFrame+1, 1 );
// assign simulation info for the registers
iBit = 0;
Saig_ManForEachLo( pAig, pObj, i )
// Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), 0 );
Ssw_SmlObjAssignConst( pSml, pObj, 0, 0 );
// assign simulation info for the primary inputs
iBit = p->nRegs;
for ( i = 0; i <= p->iFrame; i++ )
Saig_ManForEachPi( pAig, pObj, k )
Ssw_SmlObjAssignConst( pSml, pObj, Aig_InfoHasBit(p->pData, iBit++), i );
assert( iBit == p->nBits );
// run random simulation
Ssw_SmlSimulateOne( pSml );
// check if the given output has failed
RetValue = !Ssw_SmlNodeIsZero( pSml, Aig_ManPo(pAig, p->iPo) );
// write the output file
for ( i = 0; i <= p->iFrame; i++ )
{
/*
Saig_ManForEachLo( pAig, pObj, k )
{
pSims = Ssw_ObjSim(pSml, pObj->Id);
fprintf( pFile, "%d", (int)(pSims[i] != 0) );
}
fprintf( pFile, " " );
*/
Saig_ManForEachPi( pAig, pObj, k )
{
pSims = Ssw_ObjSim(pSml, pObj->Id);
fprintf( pFile, "%d", (int)(pSims[i] != 0) );
}
/*
fprintf( pFile, " " );
Saig_ManForEachPo( pAig, pObj, k )
{
pSims = Ssw_ObjSim(pSml, pObj->Id);
fprintf( pFile, "%d", (int)(pSims[i] != 0) );
}
fprintf( pFile, " " );
Saig_ManForEachLi( pAig, pObj, k )
{
pSims = Ssw_ObjSim(pSml, pObj->Id);
fprintf( pFile, "%d", (int)(pSims[i] != 0) );
}
*/
fprintf( pFile, "\n" );
}
Ssw_SmlStop( pSml );
return RetValue;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswSimSat.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [Performs resimulation using counter-examples.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswSimSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Handle the counter-example.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManResimulateBit( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr )
{
Aig_Obj_t * pObj;
int i, RetValue1, RetValue2, clk = clock();
// set the PI simulation information
Aig_ManConst1(p->pAig)->fMarkB = 1;
Aig_ManForEachPi( p->pAig, pObj, i )
pObj->fMarkB = Aig_InfoHasBit( p->pPatWords, i );
// simulate internal nodes
Aig_ManForEachNode( p->pAig, pObj, i )
pObj->fMarkB = ( Aig_ObjFanin0(pObj)->fMarkB ^ Aig_ObjFaninC0(pObj) )
& ( Aig_ObjFanin1(pObj)->fMarkB ^ Aig_ObjFaninC1(pObj) );
// check equivalence classes
RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 0 );
RetValue2 = Ssw_ClassesRefine( p->ppClasses, 0 );
// make sure refinement happened
if ( Aig_ObjIsConst1(pRepr) )
{
assert( RetValue1 );
if ( RetValue1 == 0 )
printf( "\nSsw_ManResimulateBit() Error: RetValue1 does not hold.\n" );
}
else
{
assert( RetValue2 );
if ( RetValue2 == 0 )
printf( "\nSsw_ManResimulateBit() Error: RetValue2 does not hold.\n" );
}
p->timeSimSat += clock() - clk;
}
/**Function*************************************************************
Synopsis [Verifies the result of simulation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManResimulateWordVerify( Ssw_Man_t * p, int f )
{
Aig_Obj_t * pObj, * pObjFraig;
unsigned uWord;
int Value1, Value2;
int i, nVarNum, Counter = 0;
Aig_ManForEachObj( p->pAig, pObj, i )
{
pObjFraig = Ssw_ObjFrame( p, pObj, f );
if ( pObjFraig == NULL )
continue;
nVarNum = Ssw_ObjSatNum( p, Aig_Regular(pObjFraig) );
if ( nVarNum == 0 )
continue;
Value1 = Ssw_ManGetSatVarValue( p, pObj, f );
uWord = Ssw_SmlObjGetWord( p->pSml, pObj, 0, 0 );
Value2 = ((uWord != 0) ^ pObj->fPhase);
Counter += (Value1 != Value2);
if ( Value1 != Value2 )
{
/*
int Value1f = Ssw_ManGetSatVarValue( p, Aig_ObjFanin0(pObj), f );
int Value2f = Ssw_ManGetSatVarValue( p, Aig_ObjFanin1(pObj), f );
*/
int x = 0;
int Value3 = Ssw_ManGetSatVarValue( p, pObj, f );
}
}
if ( Counter )
printf( "Counter = %d.\n", Counter );
}
/**Function*************************************************************
Synopsis [Handle the counter-example.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManResimulateWord( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f )
{
int RetValue1, RetValue2, clk = clock();
// set the PI simulation information
Ssw_SmlAssignDist1Plus( p->pSml, p->pPatWords );
// simulate internal nodes
Ssw_SmlSimulateOne( p->pSml );
Ssw_ManResimulateWordVerify( p, f );
// check equivalence classes
RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
// make sure refinement happened
if ( Aig_ObjIsConst1(pRepr) )
{
assert( RetValue1 );
if ( RetValue1 == 0 )
printf( "\nSsw_ManResimulateWord() Error: RetValue1 does not hold.\n" );
}
else
{
assert( RetValue2 );
if ( RetValue2 == 0 )
printf( "\nSsw_ManResimulateWord() Error: RetValue2 does not hold.\n" );
}
p->timeSimSat += clock() - clk;
}
/**Function*************************************************************
Synopsis [Handle the counter-example.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManResimulateWord2( Ssw_Man_t * p, Aig_Obj_t * pCand, Aig_Obj_t * pRepr, int f )
{
int RetValue1, RetValue2, clk = clock();
// set the PI simulation information
Ssw_SmlAssignDist1Plus( p->pSml, p->pPatWords2 );
// simulate internal nodes
Ssw_SmlSimulateOne( p->pSml );
Ssw_ManResimulateWordVerify( p, f );
// check equivalence classes
RetValue1 = Ssw_ClassesRefineConst1( p->ppClasses, 1 );
RetValue2 = Ssw_ClassesRefine( p->ppClasses, 1 );
// make sure refinement happened
if ( Aig_ObjIsConst1(pRepr) )
{
assert( RetValue1 );
if ( RetValue1 == 0 )
printf( "\nSsw_ManResimulateWord() Error: RetValue1 does not hold.\n" );
}
else
{
assert( RetValue2 );
if ( RetValue2 == 0 )
printf( "\nSsw_ManResimulateWord() Error: RetValue2 does not hold.\n" );
}
p->timeSimSat += clock() - clk;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswSweep.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [One round of SAT sweeping.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswSweep.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
#include "bar.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Mark nodes affected by sweep in the previous iteration.]
Description [Assumes that affected nodes are in p->ppClasses->vRefined.]
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_ManSweepMarkRefinement( Ssw_Man_t * p )
{
Vec_Ptr_t * vRefined, * vSupp;
Aig_Obj_t * pObj, * pObjLo, * pObjLi;
int i, k;
vRefined = Ssw_ClassesGetRefined( p->ppClasses );
if ( Vec_PtrSize(vRefined) == 0 )
{
Aig_ManForEachObj( p->pAig, pObj, i )
pObj->fMarkA = 1;
return;
}
// mark the nodes to be refined
Aig_ManCleanMarkA( p->pAig );
Vec_PtrForEachEntry( vRefined, pObj, i )
{
if ( Aig_ObjIsPi(pObj) )
{
pObj->fMarkA = 1;
continue;
}
assert( Aig_ObjIsNode(pObj) );
vSupp = Aig_Support( p->pAig, pObj );
Vec_PtrForEachEntry( vSupp, pObjLo, k )
pObjLo->fMarkA = 1;
Vec_PtrFree( vSupp );
}
// mark refinement
Aig_ManForEachNode( p->pAig, pObj, i )
pObj->fMarkA = Aig_ObjFanin0(pObj)->fMarkA | Aig_ObjFanin1(pObj)->fMarkA;
Saig_ManForEachLi( p->pAig, pObj, i )
pObj->fMarkA |= Aig_ObjFanin0(pObj)->fMarkA;
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
pObjLo->fMarkA |= pObjLi->fMarkA;
}
/**Function*************************************************************
Synopsis [Retrives value of the PI in the original AIG.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManGetSatVarValue( Ssw_Man_t * p, Aig_Obj_t * pObj, int f )
{
Aig_Obj_t * pObjFraig;
int nVarNum, Value;
// assert( Aig_ObjIsPi(pObj) );
pObjFraig = Ssw_ObjFrame( p, pObj, f );
nVarNum = Ssw_ObjSatNum( p, Aig_Regular(pObjFraig) );
assert( nVarNum > 0 );
if ( nVarNum == 0 )
printf( "Variable is not assigned.\n" );
Value = (!nVarNum)? 0 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pSat, nVarNum ));
// Value = (Aig_IsComplement(pObjFraig) ^ ((!nVarNum)? 0 : sat_solver_var_value( p->pSat, nVarNum )));
// Value = (!nVarNum)? Aig_ManRandom(0) & 1 : (Aig_IsComplement(pObjFraig) ^ sat_solver_var_value( p->pSat, nVarNum ));
if ( p->pPars->fPolarFlip )
{
if ( Aig_Regular(pObjFraig)->fPhase ) Value ^= 1;
}
return Value;
}
/**Function*************************************************************
Synopsis [Copy pattern from the solver into the internal storage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlSavePatternAig( Ssw_Man_t * p, int f )
{
Aig_Obj_t * pObj;
int i;
memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
Aig_ManForEachPi( p->pAig, pObj, i )
if ( Ssw_ManGetSatVarValue( p, pObj, f ) )
Aig_InfoSetBit( p->pPatWords, i );
}
/**Function*************************************************************
Synopsis [Copy pattern from the solver into the internal storage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlSavePatternAig2( Ssw_Man_t * p, int f )
{
Aig_Obj_t * pObj;
int i;
memset( p->pPatWords2, 0, sizeof(unsigned) * p->nPatWords );
Aig_ManForEachPi( p->pAig, pObj, i )
if ( Ssw_ManGetSatVarValue( p, pObj, f ) )
Aig_InfoSetBit( p->pPatWords2, i );
}
/**Function*************************************************************
Synopsis [Copy pattern from the solver into the internal storage.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Ssw_SmlSavePatternAigPhase( Ssw_Man_t * p, int f )
{
Aig_Obj_t * pObj;
int i;
memset( p->pPatWords, 0, sizeof(unsigned) * p->nPatWords );
Aig_ManForEachPi( p->pAig, pObj, i )
if ( Aig_ObjPhaseReal( Ssw_ObjFrame(p, pObj, f) ) )
Aig_InfoSetBit( p->pPatWords, i );
}
/**Function*************************************************************
Synopsis [Performs fraiging for one node.]
Description [Returns the fraiged node.]
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManSweepNode( Ssw_Man_t * p, Aig_Obj_t * pObj, int f, int fBmc )
{
Aig_Obj_t * pObjRepr, * pObjFraig, * pObjFraig2, * pObjReprFraig;
int RetValue;
// get representative of this class
pObjRepr = Aig_ObjRepr( p->pAig, pObj );
if ( pObjRepr == NULL )
return 0;
// get the fraiged node
pObjFraig = Ssw_ObjFrame( p, pObj, f );
// get the fraiged representative
pObjReprFraig = Ssw_ObjFrame( p, pObjRepr, f );
// check if constant 0 pattern distinquishes these nodes
assert( pObjFraig != NULL && pObjReprFraig != NULL );
if ( (pObj->fPhase == pObjRepr->fPhase) != (Aig_ObjPhaseReal(pObjFraig) == Aig_ObjPhaseReal(pObjReprFraig)) )
{
p->nStrangers++;
Ssw_SmlSavePatternAigPhase( p, f );
}
else
{
// if the fraiged nodes are the same, return
if ( Aig_Regular(pObjFraig) == Aig_Regular(pObjReprFraig) )
return 0;
// count the number of skipped calls
if ( !pObj->fMarkA && !pObjRepr->fMarkA )
p->nRefSkip++;
else
p->nRefUse++;
// call equivalence checking
if ( p->pPars->fSkipCheck && !fBmc && !pObj->fMarkA && !pObjRepr->fMarkA )
RetValue = 1;
else if ( Aig_Regular(pObjFraig) != Aig_ManConst1(p->pFrames) )
RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
else
RetValue = Ssw_NodesAreEquiv( p, Aig_Regular(pObjFraig), Aig_Regular(pObjReprFraig) );
if ( RetValue == 1 ) // proved equivalent
{
pObjFraig2 = Aig_NotCond( pObjReprFraig, pObj->fPhase ^ pObjRepr->fPhase );
Ssw_ObjSetFrame( p, pObj, f, pObjFraig2 );
return 0;
}
if ( RetValue == -1 ) // timed out
{
Ssw_ClassesRemoveNode( p->ppClasses, pObj );
return 1;
}
// check if skipping calls works correctly
if ( p->pPars->fSkipCheck && !fBmc && !pObj->fMarkA && !pObjRepr->fMarkA )
{
assert( 0 );
printf( "\nSsw_ManSweepNode(): Error!\n" );
}
// disproved the equivalence
Ssw_SmlSavePatternAig( p, f );
}
if ( !fBmc && p->pPars->fUniqueness && p->pPars->nFramesK > 1 &&
Ssw_ManUniqueOne( p, pObjRepr, pObj ) && p->iOutputLit == -1 )
{
if ( Ssw_ManUniqueAddConstraint( p, p->vCommon, 0, 1 ) )
{
int RetValue2 = Ssw_NodesAreEquiv( p, Aig_Regular(pObjReprFraig), Aig_Regular(pObjFraig) );
p->iOutputLit = -1;
{
int Flag = 0;
if ( Flag )
{
Aig_Obj_t * pFan0 = Aig_ObjFanin0(pObj);
Aig_Obj_t * pFan1 = Aig_ObjFanin1(pObj);
Aig_Obj_t * pFan00 = Aig_ObjFanin0(pFan0);
Aig_Obj_t * pFan01 = Aig_ObjFanin1(pFan0);
Aig_Obj_t * pFan10 = Aig_ObjFanin0(pFan1);
Aig_Obj_t * pFan11 = Aig_ObjFanin1(pFan1);
}
}
if ( RetValue2 == 0 )
{
int x = Ssw_ManUniqueOne( p, pObjRepr, pObj );
// Ssw_SmlSavePatternAig2( p, f );
// Ssw_ManResimulateWord2( p, pObj, pObjRepr, f );
Ssw_SmlSavePatternAig( p, f );
Ssw_ManResimulateWord( p, pObj, pObjRepr, f );
if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
printf( "Ssw_ManSweepNode(): Refinement did not happen!!!!!!!!!!!!!!!!!!!!.\n" );
return 1;
}
return 0;
/*
int RetValue;
assert( p->iOutputLit > -1 );
RetValue = Ssw_ManSweepNode( p, pObj, f, 0 );
p->iOutputLit = -1;
return RetValue;
*/
}
}
if ( p->pPars->nConstrs == 0 )
Ssw_ManResimulateWord( p, pObj, pObjRepr, f );
else
Ssw_ManResimulateBit( p, pObj, pObjRepr );
assert( Aig_ObjRepr( p->pAig, pObj ) != pObjRepr );
if ( Aig_ObjRepr( p->pAig, pObj ) == pObjRepr )
printf( "Ssw_ManSweepNode(): Refinement did not happen.\n" );
return 1;
}
/**Function*************************************************************
Synopsis [Performs fraiging for the internal nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManSweepBmc( Ssw_Man_t * p )
{
Bar_Progress_t * pProgress = NULL;
Aig_Obj_t * pObj, * pObjNew, * pObjLi, * pObjLo;
int i, f, clk;
clk = clock();
// start initialized timeframes
p->pFrames = Aig_ManStart( Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
Saig_ManForEachLo( p->pAig, pObj, i )
Ssw_ObjSetFrame( p, pObj, 0, Aig_ManConst0(p->pFrames) );
// sweep internal nodes
p->fRefined = 0;
if ( p->pPars->fVerbose )
pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) * p->pPars->nFramesK );
Ssw_ManStartSolver( p );
for ( f = 0; f < p->pPars->nFramesK; f++ )
{
// map constants and PIs
Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
Saig_ManForEachPi( p->pAig, pObj, i )
{
pObjNew = Aig_ObjCreatePi(p->pFrames);
Ssw_ObjSetFrame( p, pObj, f, pObjNew );
Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) );
}
// sweep internal nodes
Aig_ManForEachNode( p->pAig, pObj, i )
{
if ( p->pPars->fVerbose )
Bar_ProgressUpdate( pProgress, Aig_ManObjNumMax(p->pAig) * f + i, NULL );
pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
Ssw_ObjSetFrame( p, pObj, f, pObjNew );
p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 1 );
}
// quit if this is the last timeframe
if ( f == p->pPars->nFramesK - 1 )
break;
// transfer latch input to the latch outputs
// build logic cones for register outputs
Saig_ManForEachLiLo( p->pAig, pObjLi, pObjLo, i )
{
pObjNew = Ssw_ObjChild0Fra(p, pObjLi,f);
Ssw_ObjSetFrame( p, pObjLo, f+1, pObjNew );
Ssw_CnfNodeAddToSolver( p, Aig_Regular(pObjNew) );
}
}
if ( p->pPars->fVerbose )
Bar_ProgressStop( pProgress );
// cleanup
// Ssw_ClassesCheck( p->ppClasses );
p->timeBmc += clock() - clk;
return p->fRefined;
}
/**Function*************************************************************
Synopsis [Performs fraiging for the internal nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManSweep( Ssw_Man_t * p )
{
Bar_Progress_t * pProgress = NULL;
Aig_Obj_t * pObj, * pObj2, * pObjNew;
int nConstrPairs, clk, i, f;
int v;
// perform speculative reduction
clk = clock();
// create timeframes
p->pFrames = Ssw_FramesWithClasses( p );
// add constraints
Ssw_ManStartSolver( p );
// nConstrPairs = Aig_ManPoNum(p->pFrames)-Aig_ManRegNum(p->pAig);
nConstrPairs = Aig_ManPoNum(p->pFrames)-p->nFrames*Aig_ManRegNum(p->pAig);
assert( (nConstrPairs & 1) == 0 );
for ( i = 0; i < nConstrPairs; i += 2 )
{
pObj = Aig_ManPo( p->pFrames, i );
pObj2 = Aig_ManPo( p->pFrames, i+1 );
Ssw_NodesAreConstrained( p, Aig_ObjChild0(pObj), Aig_ObjChild0(pObj2) );
}
/*
// build logic cones for register inputs
for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ )
{
pObj = Aig_ManPo( p->pFrames, nConstrPairs + i );
Ssw_CnfNodeAddToSolver( p, Aig_ObjFanin0(pObj) );
}
*/
p->timeReduce += clock() - clk;
// mark nodes that do not have to be refined
clk = clock();
if ( p->pPars->fSkipCheck )
Ssw_ManSweepMarkRefinement( p );
p->timeMarkCones += clock() - clk;
//Ssw_ManUnique( p );
// map constants and PIs of the last frame
f = p->pPars->nFramesK;
Ssw_ObjSetFrame( p, Aig_ManConst1(p->pAig), f, Aig_ManConst1(p->pFrames) );
Saig_ManForEachPi( p->pAig, pObj, i )
Ssw_ObjSetFrame( p, pObj, f, Aig_ObjCreatePi(p->pFrames) );
////
// bring up the previous frames
// if ( p->pPars->fUniqueness )
for ( v = 0; v <= f; v++ )
// Saig_ManForEachLo( p->pAig, pObj, i )
Aig_ManForEachPi( p->pAig, pObj, i )
{
/*
if ( i == 53 && v == 1 )
{
int x = 0;
}
*/
Ssw_CnfNodeAddToSolver( p, Aig_Regular(Ssw_ObjFrame(p, pObj, v)) );
}
////
sat_solver_simplify( p->pSat );
// make sure LOs are assigned
Saig_ManForEachLo( p->pAig, pObj, i )
assert( Ssw_ObjFrame( p, pObj, f ) != NULL );
// sweep internal nodes
p->fRefined = 0;
p->nSatFailsReal = 0;
p->nRefUse = p->nRefSkip = 0;
p->nUniques = 0;
Ssw_ClassesClearRefined( p->ppClasses );
if ( p->pPars->fVerbose )
pProgress = Bar_ProgressStart( stdout, Aig_ManObjNumMax(p->pAig) );
Aig_ManForEachObj( p->pAig, pObj, i )
{
if ( p->pPars->fVerbose )
Bar_ProgressUpdate( pProgress, i, NULL );
if ( Saig_ObjIsLo(p->pAig, pObj) )
p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0 );
else if ( Aig_ObjIsNode(pObj) )
{
pObj->fMarkA = Aig_ObjFanin0(pObj)->fMarkA | Aig_ObjFanin1(pObj)->fMarkA;
pObjNew = Aig_And( p->pFrames, Ssw_ObjChild0Fra(p, pObj, f), Ssw_ObjChild1Fra(p, pObj, f) );
Ssw_ObjSetFrame( p, pObj, f, pObjNew );
p->fRefined |= Ssw_ManSweepNode( p, pObj, f, 0 );
}
}
p->nSatFailsTotal += p->nSatFailsReal;
if ( p->pPars->fVerbose )
Bar_ProgressStop( pProgress );
// cleanup
// Ssw_ClassesCheck( p->ppClasses );
return p->fRefined;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
/**CFile****************************************************************
FileName [sswSat.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Inductive prover with constraints.]
Synopsis [On-demand uniqueness constraints.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - September 1, 2008.]
Revision [$Id: sswSat.c,v 1.00 2008/09/01 00:00:00 alanmi Exp $]
***********************************************************************/
#include "sswInt.h"
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Returns the result of merging the two vectors.]
Description [Assumes that the vectors are sorted in the increasing order.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_PtrTwoMerge( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr )
{
Aig_Obj_t ** pBeg = (Aig_Obj_t **)vArr->pArray;
Aig_Obj_t ** pBeg1 = (Aig_Obj_t **)vArr1->pArray;
Aig_Obj_t ** pBeg2 = (Aig_Obj_t **)vArr2->pArray;
Aig_Obj_t ** pEnd1 = (Aig_Obj_t **)vArr1->pArray + vArr1->nSize;
Aig_Obj_t ** pEnd2 = (Aig_Obj_t **)vArr2->pArray + vArr2->nSize;
Vec_PtrGrow( vArr, Vec_PtrSize(vArr1) + Vec_PtrSize(vArr2) );
pBeg = (Aig_Obj_t **)vArr->pArray;
while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
{
if ( (*pBeg1)->Id == (*pBeg2)->Id )
*pBeg++ = *pBeg1++, pBeg2++;
else if ( (*pBeg1)->Id < (*pBeg2)->Id )
*pBeg++ = *pBeg1++;
else
*pBeg++ = *pBeg2++;
}
while ( pBeg1 < pEnd1 )
*pBeg++ = *pBeg1++;
while ( pBeg2 < pEnd2 )
*pBeg++ = *pBeg2++;
vArr->nSize = pBeg - (Aig_Obj_t **)vArr->pArray;
assert( vArr->nSize <= vArr->nCap );
assert( vArr->nSize >= vArr1->nSize );
assert( vArr->nSize >= vArr2->nSize );
}
/**Function*************************************************************
Synopsis [Returns the result of merging the two vectors.]
Description [Assumes that the vectors are sorted in the increasing order.]
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Vec_PtrTwoCommon( Vec_Ptr_t * vArr1, Vec_Ptr_t * vArr2, Vec_Ptr_t * vArr )
{
Aig_Obj_t ** pBeg = (Aig_Obj_t **)vArr->pArray;
Aig_Obj_t ** pBeg1 = (Aig_Obj_t **)vArr1->pArray;
Aig_Obj_t ** pBeg2 = (Aig_Obj_t **)vArr2->pArray;
Aig_Obj_t ** pEnd1 = (Aig_Obj_t **)vArr1->pArray + vArr1->nSize;
Aig_Obj_t ** pEnd2 = (Aig_Obj_t **)vArr2->pArray + vArr2->nSize;
Vec_PtrGrow( vArr, AIG_MIN( Vec_PtrSize(vArr1), Vec_PtrSize(vArr2) ) );
pBeg = (Aig_Obj_t **)vArr->pArray;
while ( pBeg1 < pEnd1 && pBeg2 < pEnd2 )
{
if ( (*pBeg1)->Id == (*pBeg2)->Id )
*pBeg++ = *pBeg1++, pBeg2++;
else if ( (*pBeg1)->Id < (*pBeg2)->Id )
// *pBeg++ = *pBeg1++;
pBeg1++;
else
// *pBeg++ = *pBeg2++;
pBeg2++;
}
// while ( pBeg1 < pEnd1 )
// *pBeg++ = *pBeg1++;
// while ( pBeg2 < pEnd2 )
// *pBeg++ = *pBeg2++;
vArr->nSize = pBeg - (Aig_Obj_t **)vArr->pArray;
assert( vArr->nSize <= vArr->nCap );
assert( vArr->nSize <= vArr1->nSize );
assert( vArr->nSize <= vArr2->nSize );
}
/**Function*************************************************************
Synopsis [Returns 1 if uniqueness constraints can be added.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManUniqueOne( Ssw_Man_t * p, Aig_Obj_t * pRepr, Aig_Obj_t * pObj )
{
int fVerbose = 1;
Aig_Obj_t * ppObjs[2], * pTemp;
Vec_Ptr_t * vSupp, * vSupp2;
int i, k, Value0, Value1, RetValue;
assert( p->pPars->nFramesK > 1 );
vSupp = Vec_PtrAlloc( 100 );
vSupp2 = Vec_PtrAlloc( 100 );
Vec_PtrClear( p->vCommon );
// compute the first support in terms of LOs
ppObjs[0] = pRepr;
ppObjs[1] = pObj;
Aig_SupportNodes( p->pAig, ppObjs, 2, vSupp );
// modify support to be in terms of LIs
k = 0;
Vec_PtrForEachEntry( vSupp, pTemp, i )
if ( Saig_ObjIsLo(p->pAig, pTemp) )
Vec_PtrWriteEntry( vSupp, k++, Saig_ObjLoToLi(p->pAig, pTemp) );
Vec_PtrShrink( vSupp, k );
// compute the support of support
Aig_SupportNodes( p->pAig, (Aig_Obj_t **)Vec_PtrArray(vSupp), Vec_PtrSize(vSupp), vSupp2 );
// return support to LO
Vec_PtrForEachEntry( vSupp, pTemp, i )
Vec_PtrWriteEntry( vSupp, i, Saig_ObjLiToLo(p->pAig, pTemp) );
// find the number of common vars
Vec_PtrSort( vSupp, Aig_ObjCompareIdIncrease );
Vec_PtrSort( vSupp2, Aig_ObjCompareIdIncrease );
Vec_PtrTwoCommon( vSupp, vSupp2, p->vCommon );
// Vec_PtrTwoMerge( vSupp, vSupp2, p->vCommon );
/*
{
Vec_Ptr_t * vNew = Vec_PtrDup(vSupp);
Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease );
if ( Vec_PtrSize(vNew) != Vec_PtrSize(vSupp) )
printf( "Not unique!\n" );
Vec_PtrFree( vNew );
Vec_PtrForEachEntry( vSupp, pTemp, i )
printf( "%d ", pTemp->Id );
printf( "\n" );
}
{
Vec_Ptr_t * vNew = Vec_PtrDup(vSupp2);
Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease );
if ( Vec_PtrSize(vNew) != Vec_PtrSize(vSupp2) )
printf( "Not unique!\n" );
Vec_PtrFree( vNew );
Vec_PtrForEachEntry( vSupp2, pTemp, i )
printf( "%d ", pTemp->Id );
printf( "\n" );
}
{
Vec_Ptr_t * vNew = Vec_PtrDup(p->vCommon);
Vec_PtrUniqify( vNew, Aig_ObjCompareIdIncrease );
if ( Vec_PtrSize(vNew) != Vec_PtrSize(p->vCommon) )
printf( "Not unique!\n" );
Vec_PtrFree( vNew );
Vec_PtrForEachEntry( p->vCommon, pTemp, i )
printf( "%d ", pTemp->Id );
printf( "\n" );
}
*/
if ( fVerbose )
printf( "Node = %5d : One = %3d. Two = %3d. Common = %3d. ",
Aig_ObjId(pObj), Vec_PtrSize(vSupp), Vec_PtrSize(vSupp2), Vec_PtrSize(p->vCommon) );
// Vec_PtrClear( vSupp );
// Vec_PtrForEachEntry( vSupp2, pTemp, i )
// Vec_PtrPush( vSupp, pTemp );
// check the current values
RetValue = 1;
// Vec_PtrForEachEntry( p->vCommon, pTemp, i )
Vec_PtrForEachEntry( vSupp, pTemp, i )
{
Value0 = Ssw_ManGetSatVarValue( p, pTemp, 0 );
Value1 = Ssw_ManGetSatVarValue( p, pTemp, 1 );
if ( Value0 != Value1 )
RetValue = 0;
if ( fVerbose )
printf( "%d", Value0 ^ Value1 );
}
if ( Vec_PtrSize(p->vCommon) == 0 )
RetValue = 0;
Vec_PtrForEachEntry( vSupp, pTemp, i )
printf( " %d", pTemp->Id );
if ( fVerbose )
printf( "\n" );
Vec_PtrClear( p->vCommon );
Vec_PtrForEachEntry( vSupp, pTemp, i )
Vec_PtrPush( p->vCommon, pTemp );
Vec_PtrFree( vSupp );
Vec_PtrFree( vSupp2 );
return RetValue;
}
/**Function*************************************************************
Synopsis [Returns the output of the uniqueness constraint.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Ssw_ManUniqueAddConstraint( Ssw_Man_t * p, Vec_Ptr_t * vCommon, int f1, int f2 )
{
Aig_Obj_t * pObj, * pObj1New, * pObj2New, * pMiter, * pTotal;
int i, pLits[2];
// int RetValue;
assert( Vec_PtrSize(vCommon) > 0 );
// generate the constraint
pTotal = Aig_ManConst0(p->pFrames);
Vec_PtrForEachEntry( vCommon, pObj, i )
{
assert( Saig_ObjIsLo(p->pAig, pObj) );
pObj1New = Ssw_ObjFrame( p, pObj, f1 );
pObj2New = Ssw_ObjFrame( p, pObj, f2 );
pMiter = Aig_Exor( p->pFrames, pObj1New, pObj2New );
pTotal = Aig_Or( p->pFrames, pTotal, pMiter );
}
/*
if ( Aig_ObjIsConst1(Aig_Regular(pTotal)) )
{
// printf( "Skipped\n" );
return 0;
}
*/
p->nUniques++;
// create CNF
// {
// int Num1 = p->nSatVars;
Ssw_CnfNodeAddToSolver( p, Aig_Regular(pTotal) );
// printf( "Created variable %d while vars are %d. (diff = %d)\n",
// Ssw_ObjSatNum( p, Aig_Regular(pTotal) ), p->nSatVars, p->nSatVars - Num1 );
// }
// add output constraint
pLits[0] = toLitCond( Ssw_ObjSatNum(p,Aig_Regular(pTotal)), Aig_IsComplement(pTotal) );
/*
RetValue = sat_solver_addclause( p->pSat, pLits, pLits + 1 );
assert( RetValue );
// simplify the solver
if ( p->pSat->qtail != p->pSat->qhead )
{
RetValue = sat_solver_simplify(p->pSat);
assert( RetValue != 0 );
}
*/
assert( p->iOutputLit == -1 );
p->iOutputLit = pLits[0];
return 1;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
...@@ -215,7 +215,7 @@ static int Abc_CommandBmc ( Abc_Frame_t * pAbc, int argc, char ** arg ...@@ -215,7 +215,7 @@ static int Abc_CommandBmc ( Abc_Frame_t * pAbc, int argc, char ** arg
static int Abc_CommandBmcInter ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandBmcInter ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandIndcut ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandIndcut ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandEnlarge ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandEnlarge ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandLocalize ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandInduction ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTraceStart ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTraceStart ( Abc_Frame_t * pAbc, int argc, char ** argv );
static int Abc_CommandTraceCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandTraceCheck ( Abc_Frame_t * pAbc, int argc, char ** argv );
...@@ -483,7 +483,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) ...@@ -483,7 +483,7 @@ void Abc_Init( Abc_Frame_t * pAbc )
Cmd_CommandAdd( pAbc, "Verification", "int", Abc_CommandBmcInter, 0 ); Cmd_CommandAdd( pAbc, "Verification", "int", Abc_CommandBmcInter, 0 );
Cmd_CommandAdd( pAbc, "Verification", "indcut", Abc_CommandIndcut, 0 ); Cmd_CommandAdd( pAbc, "Verification", "indcut", Abc_CommandIndcut, 0 );
Cmd_CommandAdd( pAbc, "Verification", "enlarge", Abc_CommandEnlarge, 1 ); Cmd_CommandAdd( pAbc, "Verification", "enlarge", Abc_CommandEnlarge, 1 );
Cmd_CommandAdd( pAbc, "Verification", "loc", Abc_CommandLocalize, 0 ); Cmd_CommandAdd( pAbc, "Verification", "ind", Abc_CommandInduction, 0 );
Cmd_CommandAdd( pAbc, "ABC8", "*r", Abc_CommandAbc8Read, 0 ); Cmd_CommandAdd( pAbc, "ABC8", "*r", Abc_CommandAbc8Read, 0 );
...@@ -620,7 +620,7 @@ int Abc_CommandPrintStats( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -620,7 +620,7 @@ int Abc_CommandPrintStats( Abc_Frame_t * pAbc, int argc, char ** argv )
fDumpResult = 0; fDumpResult = 0;
fUseLutLib = 0; fUseLutLib = 0;
fPrintTime = 0; fPrintTime = 0;
fPrintMuxes = 1; fPrintMuxes = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "fbdltmh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "fbdltmh" ) ) != EOF )
{ {
...@@ -7936,7 +7936,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -7936,7 +7936,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
*/ */
/*
pNtkRes = Abc_NtkDarTestNtk( pNtk ); pNtkRes = Abc_NtkDarTestNtk( pNtk );
if ( pNtkRes == NULL ) if ( pNtkRes == NULL )
{ {
...@@ -7945,9 +7945,9 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -7945,9 +7945,9 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv )
} }
// replace the current network // replace the current network
Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes ); Abc_FrameReplaceCurrentNetwork( pAbc, pNtkRes );
*/
Abc_NtkDarTest( pNtk );
// Abc_NtkDarTest( pNtk );
return 0; return 0;
usage: usage:
...@@ -13559,7 +13559,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -13559,7 +13559,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults // set defaults
Ssw_ManSetDefaultParams( pPars ); Ssw_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLNSplsfuvwh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLNSIplfuvwh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -13640,15 +13640,23 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -13640,15 +13640,23 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
if ( pPars->nFramesAddSim < 0 ) if ( pPars->nFramesAddSim < 0 )
goto usage; goto usage;
break; break;
case 'I':
if ( globalUtilOptind >= argc )
{
fprintf( pErr, "Command line switch \"-I\" should be followed by an integer.\n" );
goto usage;
}
pPars->nItersStop = atoi(argv[globalUtilOptind]);
globalUtilOptind++;
if ( pPars->nItersStop < 0 )
goto usage;
break;
case 'p': case 'p':
pPars->fPolarFlip ^= 1; pPars->fPolarFlip ^= 1;
break; break;
case 'l': case 'l':
pPars->fLatchCorr ^= 1; pPars->fLatchCorr ^= 1;
break; break;
case 's':
pPars->fSkipCheck ^= 1;
break;
case 'f': case 'f':
pPars->fSemiFormal ^= 1; pPars->fSemiFormal ^= 1;
break; break;
...@@ -13710,7 +13718,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -13710,7 +13718,7 @@ int Abc_CommandSeqSweep2( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: usage:
fprintf( pErr, "usage: scorr [-PQFCLNS <num>] [-plsfuvwh]\n" ); fprintf( pErr, "usage: scorr [-PQFCLNSI <num>] [-plfuvwh]\n" );
fprintf( pErr, "\t performs sequential sweep using K-step induction\n" ); fprintf( pErr, "\t performs sequential sweep using K-step induction\n" );
fprintf( pErr, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize ); fprintf( pErr, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize );
fprintf( pErr, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize ); fprintf( pErr, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize );
...@@ -13719,10 +13727,10 @@ usage: ...@@ -13719,10 +13727,10 @@ usage:
fprintf( pErr, "\t-L num : max number of levels to consider (0=all) [default = %d]\n", pPars->nMaxLevs ); fprintf( pErr, "\t-L num : max number of levels to consider (0=all) [default = %d]\n", pPars->nMaxLevs );
fprintf( pErr, "\t-N num : number of last POs treated as constraints (0=none) [default = %d]\n", pPars->nConstrs ); fprintf( pErr, "\t-N num : number of last POs treated as constraints (0=none) [default = %d]\n", pPars->nConstrs );
fprintf( pErr, "\t-S num : additional simulation frames for c-examples (0=none) [default = %d]\n", pPars->nFramesAddSim ); fprintf( pErr, "\t-S num : additional simulation frames for c-examples (0=none) [default = %d]\n", pPars->nFramesAddSim );
fprintf( pErr, "\t-I num : iteration number to stop and output SR-model (0=none) [default = %d]\n", pPars->nItersStop );
fprintf( pErr, "\t-p : toggle alighning polarity of SAT variables [default = %s]\n", pPars->fPolarFlip? "yes": "no" ); fprintf( pErr, "\t-p : toggle alighning polarity of SAT variables [default = %s]\n", pPars->fPolarFlip? "yes": "no" );
fprintf( pErr, "\t-l : toggle latch correspondence only [default = %s]\n", pPars->fLatchCorr? "yes": "no" ); fprintf( pErr, "\t-l : toggle latch correspondence only [default = %s]\n", pPars->fLatchCorr? "yes": "no" );
fprintf( pErr, "\t-s : toggle skipping unaffected cones [default = %s]\n", pPars->fSkipCheck? "yes": "no" ); // fprintf( pErr, "\t-f : toggle filtering using interative BMC [default = %s]\n", pPars->fSemiFormal? "yes": "no" );
fprintf( pErr, "\t-f : toggle filtering using interative BMC [default = %s]\n", pPars->fSemiFormal? "yes": "no" );
fprintf( pErr, "\t-u : toggle using uniqueness constraints [default = %s]\n", pPars->fUniqueness? "yes": "no" ); fprintf( pErr, "\t-u : toggle using uniqueness constraints [default = %s]\n", pPars->fUniqueness? "yes": "no" );
fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" ); fprintf( pErr, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
fprintf( pErr, "\t-w : toggle printout of flop equivalences [default = %s]\n", pPars->fFlopVerbose? "yes": "no" ); fprintf( pErr, "\t-w : toggle printout of flop equivalences [default = %s]\n", pPars->fFlopVerbose? "yes": "no" );
...@@ -16560,7 +16568,7 @@ usage: ...@@ -16560,7 +16568,7 @@ usage:
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
int Abc_CommandLocalize( Abc_Frame_t * pAbc, int argc, char ** argv ) int Abc_CommandInduction( Abc_Frame_t * pAbc, int argc, char ** argv )
{ {
FILE * pOut, * pErr; FILE * pOut, * pErr;
Abc_Ntk_t * pNtk; Abc_Ntk_t * pNtk;
...@@ -16575,8 +16583,8 @@ int Abc_CommandLocalize( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -16575,8 +16583,8 @@ int Abc_CommandLocalize( Abc_Frame_t * pAbc, int argc, char ** argv )
pErr = Abc_FrameReadErr(pAbc); pErr = Abc_FrameReadErr(pAbc);
// set defaults // set defaults
nFramesMax = 50; nFramesMax = 100;
nConfMax = 500; nConfMax = 1000;
fVerbose = 0; fVerbose = 0;
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "FCvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "FCvh" ) ) != EOF )
...@@ -16639,8 +16647,8 @@ int Abc_CommandLocalize( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -16639,8 +16647,8 @@ int Abc_CommandLocalize( Abc_Frame_t * pAbc, int argc, char ** argv )
Abc_NtkDarLocalize( pNtk, nFramesMax, nConfMax, fVerbose ); Abc_NtkDarLocalize( pNtk, nFramesMax, nConfMax, fVerbose );
return 0; return 0;
usage: usage:
fprintf( pErr, "usage: loc [-FC num] [-vh]\n" ); fprintf( pErr, "usage: ind [-FC num] [-vh]\n" );
fprintf( pErr, "\t performs localization for single-output miter\n" ); fprintf( pErr, "\t runs K-step induction for the property output\n" );
fprintf( pErr, "\t-F num : the max number of timeframes [default = %d]\n", nFramesMax ); fprintf( pErr, "\t-F num : the max number of timeframes [default = %d]\n", nFramesMax );
fprintf( pErr, "\t-C num : the max number of conflicts by SAT solver [default = %d]\n", nConfMax ); fprintf( pErr, "\t-C num : the max number of conflicts by SAT solver [default = %d]\n", nConfMax );
fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); fprintf( pErr, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" );
...@@ -19121,7 +19129,7 @@ int Abc_CommandAbc8Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -19121,7 +19129,7 @@ int Abc_CommandAbc8Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
// set defaults // set defaults
Ssw_ManSetDefaultParams( pPars ); Ssw_ManSetDefaultParams( pPars );
Extra_UtilGetoptReset(); Extra_UtilGetoptReset();
while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLNSDplsvh" ) ) != EOF ) while ( ( c = Extra_UtilGetopt( argc, argv, "PQFCLNSDplvh" ) ) != EOF )
{ {
switch ( c ) switch ( c )
{ {
...@@ -19219,9 +19227,6 @@ int Abc_CommandAbc8Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -19219,9 +19227,6 @@ int Abc_CommandAbc8Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
case 'l': case 'l':
pPars->fLatchCorr ^= 1; pPars->fLatchCorr ^= 1;
break; break;
case 's':
pPars->fSkipCheck ^= 1;
break;
case 'v': case 'v':
pPars->fVerbose ^= 1; pPars->fVerbose ^= 1;
break; break;
...@@ -19268,7 +19273,7 @@ int Abc_CommandAbc8Scorr( Abc_Frame_t * pAbc, int argc, char ** argv ) ...@@ -19268,7 +19273,7 @@ int Abc_CommandAbc8Scorr( Abc_Frame_t * pAbc, int argc, char ** argv )
return 0; return 0;
usage: usage:
fprintf( stdout, "usage: *scorr [-PQFCLNSD <num>] [-plsvh]\n" ); fprintf( stdout, "usage: *scorr [-PQFCLNSD <num>] [-plvh]\n" );
fprintf( stdout, "\t performs sequential sweep using K-step induction\n" ); fprintf( stdout, "\t performs sequential sweep using K-step induction\n" );
fprintf( stdout, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize ); fprintf( stdout, "\t-P num : max partition size (0 = no partitioning) [default = %d]\n", pPars->nPartSize );
fprintf( stdout, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize ); fprintf( stdout, "\t-Q num : partition overlap (0 = no overlap) [default = %d]\n", pPars->nOverSize );
...@@ -19280,7 +19285,6 @@ usage: ...@@ -19280,7 +19285,6 @@ usage:
fprintf( stdout, "\t-D num : min size of a clock domain used for synthesis [default = %d]\n", pPars->nMinDomSize ); fprintf( stdout, "\t-D num : min size of a clock domain used for synthesis [default = %d]\n", pPars->nMinDomSize );
fprintf( stdout, "\t-p : toggle alighning polarity of SAT variables [default = %s]\n", pPars->fPolarFlip? "yes": "no" ); fprintf( stdout, "\t-p : toggle alighning polarity of SAT variables [default = %s]\n", pPars->fPolarFlip? "yes": "no" );
fprintf( stdout, "\t-l : toggle latch correspondence only [default = %s]\n", pPars->fLatchCorr? "yes": "no" ); fprintf( stdout, "\t-l : toggle latch correspondence only [default = %s]\n", pPars->fLatchCorr? "yes": "no" );
fprintf( stdout, "\t-s : toggle skipping unaffected cones [default = %s]\n", pPars->fSkipCheck? "yes": "no" );
fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" ); fprintf( stdout, "\t-v : toggle verbose output [default = %s]\n", pPars->fVerbose? "yes": "no" );
fprintf( stdout, "\t-h : print the command usage\n"); fprintf( stdout, "\t-h : print the command usage\n");
return 1; return 1;
......
...@@ -1465,7 +1465,7 @@ Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, in ...@@ -1465,7 +1465,7 @@ Abc_Ntk_t * Abc_NtkDarLcorrNew( Abc_Ntk_t * pNtk, int nVarsMax, int nConfMax, in
int Abc_NtkDarBmc( Abc_Ntk_t * pNtk, int nFrames, int nSizeMax, int nBTLimit, int fRewrite, int fNewAlgo, int fVerbose ) int Abc_NtkDarBmc( Abc_Ntk_t * pNtk, int nFrames, int nSizeMax, int nBTLimit, int fRewrite, int fNewAlgo, int fVerbose )
{ {
Aig_Man_t * pMan; Aig_Man_t * pMan;
int RetValue = -1, clk = clock(); int status, RetValue = -1, clk = clock();
// derive the AIG manager // derive the AIG manager
pMan = Abc_NtkToDar( pNtk, 0, 1 ); pMan = Abc_NtkToDar( pNtk, 0, 1 );
if ( pMan == NULL ) if ( pMan == NULL )
...@@ -1494,6 +1494,7 @@ int Abc_NtkDarBmc( Abc_Ntk_t * pNtk, int nFrames, int nSizeMax, int nBTLimit, in ...@@ -1494,6 +1494,7 @@ int Abc_NtkDarBmc( Abc_Ntk_t * pNtk, int nFrames, int nSizeMax, int nBTLimit, in
} }
else else
{ {
/*
Fra_BmcPerformSimple( pMan, nFrames, nBTLimit, fRewrite, fVerbose ); Fra_BmcPerformSimple( pMan, nFrames, nBTLimit, fRewrite, fVerbose );
FREE( pNtk->pModel ); FREE( pNtk->pModel );
FREE( pNtk->pSeqModel ); FREE( pNtk->pSeqModel );
...@@ -1509,8 +1510,30 @@ int Abc_NtkDarBmc( Abc_Ntk_t * pNtk, int nFrames, int nSizeMax, int nBTLimit, in ...@@ -1509,8 +1510,30 @@ int Abc_NtkDarBmc( Abc_Ntk_t * pNtk, int nFrames, int nSizeMax, int nBTLimit, in
printf( "No output was asserted in %d frames. ", nFrames ); printf( "No output was asserted in %d frames. ", nFrames );
RetValue = 1; RetValue = 1;
} }
*/
int iFrame;
RetValue = Ssw_BmcDynamic( pMan, nFrames, nBTLimit, fVerbose, &iFrame );
FREE( pNtk->pModel );
FREE( pNtk->pSeqModel );
pNtk->pSeqModel = pMan->pSeqModel; pMan->pSeqModel = NULL;
if ( RetValue == 1 )
printf( "No output was asserted in %d frames. ", iFrame );
else if ( RetValue == -1 )
printf( "No output was asserted in %d frames. Reached conflict limit (%d). ", iFrame, nBTLimit );
else // if ( RetValue == 0 )
{
Fra_Cex_t * pCex = pNtk->pSeqModel;
printf( "Output %d was asserted in frame %d (use \"write_counter\" to dump a witness). ", pCex->iPo, pCex->iFrame );
}
} }
PRT( "Time", clock() - clk ); PRT( "Time", clock() - clk );
// verify counter-example
if ( pNtk->pSeqModel )
{
status = Ssw_SmlRunCounterExample( pMan, pNtk->pSeqModel );
if ( status == 0 )
printf( "Abc_NtkDarBmc(): Counter-example verification has FAILED.\n" );
}
Aig_ManStop( pMan ); Aig_ManStop( pMan );
return RetValue; return RetValue;
} }
...@@ -2128,7 +2151,7 @@ void Abc_NtkDarLocalize( Abc_Ntk_t * pNtk, int nFramesMax, int nConfMax, int fVe ...@@ -2128,7 +2151,7 @@ void Abc_NtkDarLocalize( Abc_Ntk_t * pNtk, int nFramesMax, int nConfMax, int fVe
pMan = Abc_NtkToDar( pNtk, 0, 1 ); pMan = Abc_NtkToDar( pNtk, 0, 1 );
if ( pMan == NULL ) if ( pMan == NULL )
return; return;
RetValue = Saig_ManLocalization( pTemp = pMan, nFramesMax, nConfMax, fVerbose ); RetValue = Saig_ManInduction( pTemp = pMan, nFramesMax, nConfMax, fVerbose );
Aig_ManStop( pTemp ); Aig_ManStop( pTemp );
if ( RetValue == 1 ) if ( RetValue == 1 )
{ {
......
...@@ -114,7 +114,6 @@ int Abc_NtkCompareAndSaveBest( Abc_Ntk_t * pNtk ) ...@@ -114,7 +114,6 @@ int Abc_NtkCompareAndSaveBest( Abc_Ntk_t * pNtk )
void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDumpResult, int fUseLutLib, int fPrintMuxes ) void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored, int fSaveBest, int fDumpResult, int fUseLutLib, int fPrintMuxes )
{ {
int Num; int Num;
if ( fSaveBest ) if ( fSaveBest )
Abc_NtkCompareAndSaveBest( pNtk ); Abc_NtkCompareAndSaveBest( pNtk );
if ( fDumpResult ) if ( fDumpResult )
...@@ -147,15 +146,11 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored, int fSave ...@@ -147,15 +146,11 @@ void Abc_NtkPrintStats( FILE * pFile, Abc_Ntk_t * pNtk, int fFactored, int fSave
fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) ); fprintf( pFile, " and = %5d", Abc_NtkNodeNum(pNtk) );
if ( (Num = Abc_NtkGetChoiceNum(pNtk)) ) if ( (Num = Abc_NtkGetChoiceNum(pNtk)) )
fprintf( pFile, " (choice = %d)", Num ); fprintf( pFile, " (choice = %d)", Num );
if ( (Num = Abc_NtkGetExorNum(pNtk)) )
fprintf( pFile, " (exor = %d)", Num );
// if ( Num2 = Abc_NtkGetMuxNum(pNtk) )
// fprintf( pFile, " (mux = %d)", Num2-Num );
// if ( Num2 )
// fprintf( pFile, " (other = %d)", Abc_NtkNodeNum(pNtk)-3*Num2 );
if ( fPrintMuxes ) if ( fPrintMuxes )
{ {
extern int Abc_NtkCountMuxes( Abc_Ntk_t * pNtk ); extern int Abc_NtkCountMuxes( Abc_Ntk_t * pNtk );
Num = Abc_NtkGetExorNum(pNtk);
fprintf( pFile, " (exor = %d)", Num );
fprintf( pFile, " (mux = %d)", Abc_NtkCountMuxes(pNtk)-Num ); fprintf( pFile, " (mux = %d)", Abc_NtkCountMuxes(pNtk)-Num );
fprintf( pFile, " (pure and = %d)", Abc_NtkNodeNum(pNtk) - (Abc_NtkCountMuxes(pNtk) * 3) ); fprintf( pFile, " (pure and = %d)", Abc_NtkNodeNum(pNtk) - (Abc_NtkCountMuxes(pNtk) * 3) );
} }
......
...@@ -382,12 +382,12 @@ static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin ) ...@@ -382,12 +382,12 @@ static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry ) static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Fill )
{ {
int i; int i;
Vec_IntGrow( p, nSize ); Vec_IntGrow( p, nSize );
for ( i = 0; i < nSize; i++ ) for ( i = 0; i < nSize; i++ )
p->pArray[i] = Entry; p->pArray[i] = Fill;
p->nSize = nSize; p->nSize = nSize;
} }
...@@ -402,20 +402,40 @@ static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry ) ...@@ -402,20 +402,40 @@ static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry ) static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Fill )
{ {
int i; int i;
if ( p->nSize >= nSize ) if ( p->nSize >= nSize )
return; return;
Vec_IntGrow( p, nSize ); if ( 2 * p->nSize > nSize )
Vec_IntGrow( p, 2 * nSize );
else
Vec_IntGrow( p, nSize );
for ( i = p->nSize; i < nSize; i++ ) for ( i = p->nSize; i < nSize; i++ )
p->pArray[i] = Entry; p->pArray[i] = Fill;
p->nSize = nSize; p->nSize = nSize;
} }
/**Function************************************************************* /**Function*************************************************************
Synopsis [] Synopsis [Returns the entry even if the place not exist.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline int Vec_IntGetEntry( Vec_Int_t * p, int i )
{
Vec_IntFillExtra( p, i + 1, 0 );
return Vec_IntEntry( p, i );
}
/**Function*************************************************************
Synopsis [Inserts the entry even if the place does not exist.]
Description [] Description []
...@@ -424,11 +444,9 @@ static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry ) ...@@ -424,11 +444,9 @@ static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry )
SeeAlso [] SeeAlso []
***********************************************************************/ ***********************************************************************/
static inline void Vec_IntWriteEntryFill( Vec_Int_t * p, int i, int Entry ) static inline void Vec_IntSetEntry( Vec_Int_t * p, int i, int Entry )
{ {
assert( i >= 0 ); Vec_IntFillExtra( p, i + 1, 0 );
if ( i >= p->nSize )
Vec_IntFillExtra( p, 2 * i, 0 );
Vec_IntWriteEntry( p, i, Entry ); Vec_IntWriteEntry( p, i, Entry );
} }
......
...@@ -718,6 +718,27 @@ int Int_ManProofTraceOne( Int_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pFin ...@@ -718,6 +718,27 @@ int Int_ManProofTraceOne( Int_Man_t * p, Sto_Cls_t * pConflict, Sto_Cls_t * pFin
Int_ManPrintResolvent( p->pResLits, p->nResLits ); Int_ManPrintResolvent( p->pResLits, p->nResLits );
Int_ManPrintClause( p, pFinal ); Int_ManPrintClause( p, pFinal );
} }
// if there are literals in the clause that are not in the resolvent
// it means that the derived resolvent is stronger than the clause
// we can replace the clause with the resolvent by removing these literals
if ( p->nResLits != (int)pFinal->nLits )
{
for ( v1 = 0; v1 < (int)pFinal->nLits; v1++ )
{
for ( v2 = 0; v2 < p->nResLits; v2++ )
if ( pFinal->pLits[v1] == p->pResLits[v2] )
break;
if ( v2 < p->nResLits )
continue;
// remove literal v1 from the final clause
pFinal->nLits--;
for ( v2 = v1; v2 < (int)pFinal->nLits; v2++ )
pFinal->pLits[v2] = pFinal->pLits[v2+1];
v1--;
}
assert( p->nResLits == (int)pFinal->nLits );
}
} }
p->timeTrace += clock() - clk; p->timeTrace += clock() - clk;
...@@ -727,6 +748,8 @@ p->timeTrace += clock() - clk; ...@@ -727,6 +748,8 @@ p->timeTrace += clock() - clk;
// Int_ManPrintInterOne( p, pFinal ); // Int_ManPrintInterOne( p, pFinal );
} }
Int_ManProofSet( p, pFinal, p->Counter ); Int_ManProofSet( p, pFinal, p->Counter );
// make sure the same proof ID is not asssigned to two consecutive clauses
assert( p->pProofNums[pFinal->Id-1] != p->Counter );
return p->Counter; return p->Counter;
} }
...@@ -754,6 +777,13 @@ int Int_ManProofRecordOne( Int_Man_t * p, Sto_Cls_t * pClause ) ...@@ -754,6 +777,13 @@ int Int_ManProofRecordOne( Int_Man_t * p, Sto_Cls_t * pClause )
// add assumptions to the trail // add assumptions to the trail
assert( !pClause->fRoot ); assert( !pClause->fRoot );
assert( p->nTrailSize == p->nRootSize ); assert( p->nTrailSize == p->nRootSize );
// if any of the clause literals are already assumed
// it means that the clause is redundant and can be skipped
for ( i = 0; i < (int)pClause->nLits; i++ )
if ( p->pAssigns[lit_var(pClause->pLits[i])] == pClause->pLits[i] )
return 1;
for ( i = 0; i < (int)pClause->nLits; i++ ) for ( i = 0; i < (int)pClause->nLits; i++ )
if ( !Int_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) ) if ( !Int_ManEnqueue( p, lit_neg(pClause->pLits[i]), NULL ) )
{ {
...@@ -769,6 +799,27 @@ int Int_ManProofRecordOne( Int_Man_t * p, Sto_Cls_t * pClause ) ...@@ -769,6 +799,27 @@ int Int_ManProofRecordOne( Int_Man_t * p, Sto_Cls_t * pClause )
return 0; return 0;
} }
// skip the clause if it is weaker or the same as the conflict clause
if ( pClause->nLits >= pConflict->nLits )
{
// check if every literal of conflict clause can be found in the given clause
int j;
for ( i = 0; i < (int)pConflict->nLits; i++ )
{
for ( j = 0; j < (int)pClause->nLits; j++ )
if ( pConflict->pLits[i] == pClause->pLits[j] )
break;
if ( j == (int)pClause->nLits ) // literal pConflict->pLits[i] is not found
break;
}
if ( i == (int)pConflict->nLits ) // all lits are found
{
// undo to the root level
Int_ManCancelUntil( p, p->nRootSize );
return 1;
}
}
// construct the proof // construct the proof
Int_ManProofTraceOne( p, pConflict, pClause ); Int_ManProofTraceOne( p, pConflict, pClause );
...@@ -854,8 +905,12 @@ int Int_ManProcessRoots( Int_Man_t * p ) ...@@ -854,8 +905,12 @@ int Int_ManProcessRoots( Int_Man_t * p )
if ( !Int_ManEnqueue( p, pClause->pLits[0], pClause ) ) if ( !Int_ManEnqueue( p, pClause->pLits[0], pClause ) )
{ {
// detected root level conflict // detected root level conflict
printf( "Error in Int_ManProcessRoots(): Detected a root-level conflict too early!\n" ); // printf( "Error in Int_ManProcessRoots(): Detected a root-level conflict too early!\n" );
assert( 0 ); // assert( 0 );
// detected root level conflict
Int_ManProofTraceOne( p, pClause, p->pCnf->pEmpty );
if ( p->fVerbose )
printf( "Found root level conflict!\n" );
return 0; return 0;
} }
} }
......
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