mirror of https://github.com/YosysHQ/abc.git
355 lines
13 KiB
C
355 lines
13 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [abcProve.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Network and node package.]
|
|
|
|
Synopsis [Proves the miter using AIG rewriting, FRAIGing, and SAT solving.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: abcProve.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include <math.h>
|
|
|
|
#include "base/abc/abc.h"
|
|
#include "proof/fraig/fraig.h"
|
|
|
|
#ifdef ABC_USE_CUDD
|
|
#include "bdd/extrab/extraBdd.h"
|
|
#endif
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
extern int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose );
|
|
extern Abc_Ntk_t * Abc_NtkFromFraig( Fraig_Man_t * pMan, Abc_Ntk_t * pNtk );
|
|
|
|
static Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, ABC_INT64_T nInspLimit, int * pRetValue, int * pNumFails, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects );
|
|
static void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, abctime clk, int fVerbose );
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Attempts to solve the miter using a number of tricks.]
|
|
|
|
Description [Returns -1 if timed out; 0 if SAT; 1 if UNSAT. Returns
|
|
a simplified version of the original network (or a constant 0 network).
|
|
In case the network is not a constant zero and a SAT assignment is found,
|
|
pNtk->pModel contains a satisfying assignment.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Abc_NtkMiterProve( Abc_Ntk_t ** ppNtk, void * pPars )
|
|
{
|
|
Prove_Params_t * pParams = (Prove_Params_t *)pPars;
|
|
Abc_Ntk_t * pNtk, * pNtkTemp;
|
|
int RetValue = -1, nIter, nSatFails, Counter;
|
|
abctime clk; //, timeStart = Abc_Clock();
|
|
ABC_INT64_T nSatConfs, nSatInspects, nInspectLimit;
|
|
|
|
// get the starting network
|
|
pNtk = *ppNtk;
|
|
assert( Abc_NtkIsStrash(pNtk) );
|
|
assert( Abc_NtkPoNum(pNtk) == 1 );
|
|
|
|
if ( pParams->fVerbose )
|
|
{
|
|
printf( "RESOURCE LIMITS: Iterations = %d. Rewriting = %s. Fraiging = %s.\n",
|
|
pParams->nItersMax, pParams->fUseRewriting? "yes":"no", pParams->fUseFraiging? "yes":"no" );
|
|
printf( "Miter = %d (%3.1f). Rwr = %d (%3.1f). Fraig = %d (%3.1f). Last = %d.\n",
|
|
pParams->nMiteringLimitStart, pParams->nMiteringLimitMulti,
|
|
pParams->nRewritingLimitStart, pParams->nRewritingLimitMulti,
|
|
pParams->nFraigingLimitStart, pParams->nFraigingLimitMulti, pParams->nMiteringLimitLast );
|
|
}
|
|
|
|
// if SAT only, solve without iteration
|
|
if ( !pParams->fUseRewriting && !pParams->fUseFraiging )
|
|
{
|
|
clk = Abc_Clock();
|
|
RetValue = Abc_NtkMiterSat( pNtk, (ABC_INT64_T)pParams->nMiteringLimitLast, (ABC_INT64_T)0, 0, NULL, NULL );
|
|
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
|
|
*ppNtk = pNtk;
|
|
return RetValue;
|
|
}
|
|
|
|
// check the current resource limits
|
|
for ( nIter = 0; nIter < pParams->nItersMax; nIter++ )
|
|
{
|
|
if ( pParams->fVerbose )
|
|
{
|
|
printf( "ITERATION %2d : Confs = %6d. FraigBTL = %3d. \n", nIter+1,
|
|
(int)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)),
|
|
(int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)) );
|
|
fflush( stdout );
|
|
}
|
|
|
|
// try brute-force SAT
|
|
clk = Abc_Clock();
|
|
nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0;
|
|
RetValue = Abc_NtkMiterSat( pNtk, (ABC_INT64_T)(pParams->nMiteringLimitStart * pow(pParams->nMiteringLimitMulti,nIter)), (ABC_INT64_T)nInspectLimit, 0, &nSatConfs, &nSatInspects );
|
|
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
|
|
if ( RetValue >= 0 )
|
|
break;
|
|
|
|
// add to the number of backtracks and inspects
|
|
pParams->nTotalBacktracksMade += nSatConfs;
|
|
pParams->nTotalInspectsMade += nSatInspects;
|
|
// check if global resource limit is reached
|
|
if ( (pParams->nTotalBacktrackLimit && pParams->nTotalBacktracksMade >= pParams->nTotalBacktrackLimit) ||
|
|
(pParams->nTotalInspectLimit && pParams->nTotalInspectsMade >= pParams->nTotalInspectLimit) )
|
|
{
|
|
printf( "Reached global limit on conflicts/inspects. Quitting.\n" );
|
|
*ppNtk = pNtk;
|
|
return -1;
|
|
}
|
|
|
|
// try rewriting
|
|
if ( pParams->fUseRewriting )
|
|
{
|
|
clk = Abc_Clock();
|
|
Counter = (int)(pParams->nRewritingLimitStart * pow(pParams->nRewritingLimitMulti,nIter));
|
|
// Counter = 1;
|
|
while ( 1 )
|
|
{
|
|
/*
|
|
extern Abc_Ntk_t * Abc_NtkIvyResyn( Abc_Ntk_t * pNtk, int fUpdateLevel, int fVerbose );
|
|
pNtk = Abc_NtkIvyResyn( pNtkTemp = pNtk, 0, 0 ); Abc_NtkDelete( pNtkTemp );
|
|
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
|
|
break;
|
|
if ( --Counter == 0 )
|
|
break;
|
|
*/
|
|
/*
|
|
Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 );
|
|
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
|
|
break;
|
|
if ( --Counter == 0 )
|
|
break;
|
|
*/
|
|
Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 );
|
|
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
|
|
break;
|
|
if ( --Counter == 0 )
|
|
break;
|
|
Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 );
|
|
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
|
|
break;
|
|
if ( --Counter == 0 )
|
|
break;
|
|
pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 ); Abc_NtkDelete( pNtkTemp );
|
|
if ( (RetValue = Abc_NtkMiterIsConstant(pNtk)) >= 0 )
|
|
break;
|
|
if ( --Counter == 0 )
|
|
break;
|
|
}
|
|
Abc_NtkMiterPrint( pNtk, "Rewriting ", clk, pParams->fVerbose );
|
|
}
|
|
|
|
if ( pParams->fUseFraiging )
|
|
{
|
|
// try FRAIGing
|
|
clk = Abc_Clock();
|
|
nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0;
|
|
pNtk = Abc_NtkMiterFraig( pNtkTemp = pNtk, (int)(pParams->nFraigingLimitStart * pow(pParams->nFraigingLimitMulti,nIter)), nInspectLimit, &RetValue, &nSatFails, &nSatConfs, &nSatInspects ); Abc_NtkDelete( pNtkTemp );
|
|
Abc_NtkMiterPrint( pNtk, "FRAIGing ", clk, pParams->fVerbose );
|
|
// printf( "NumFails = %d\n", nSatFails );
|
|
if ( RetValue >= 0 )
|
|
break;
|
|
|
|
// add to the number of backtracks and inspects
|
|
pParams->nTotalBacktracksMade += nSatConfs;
|
|
pParams->nTotalInspectsMade += nSatInspects;
|
|
// check if global resource limit is reached
|
|
if ( (pParams->nTotalBacktrackLimit && pParams->nTotalBacktracksMade >= pParams->nTotalBacktrackLimit) ||
|
|
(pParams->nTotalInspectLimit && pParams->nTotalInspectsMade >= pParams->nTotalInspectLimit) )
|
|
{
|
|
printf( "Reached global limit on conflicts/inspects. Quitting.\n" );
|
|
*ppNtk = pNtk;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// try to prove it using brute force SAT
|
|
#ifdef ABC_USE_CUDD
|
|
if ( RetValue < 0 && pParams->fUseBdds )
|
|
{
|
|
if ( pParams->fVerbose )
|
|
{
|
|
printf( "Attempting BDDs with node limit %d ...\n", pParams->nBddSizeLimit );
|
|
fflush( stdout );
|
|
}
|
|
clk = Abc_Clock();
|
|
pNtk = Abc_NtkCollapse( pNtkTemp = pNtk, pParams->nBddSizeLimit, 0, pParams->fBddReorder, 0, 0, 0 );
|
|
if ( pNtk )
|
|
{
|
|
Abc_NtkDelete( pNtkTemp );
|
|
RetValue = ( (Abc_NtkNodeNum(pNtk) == 1) && (Abc_ObjFanin0(Abc_NtkPo(pNtk,0))->pData == Cudd_ReadLogicZero((DdManager *)pNtk->pManFunc)) );
|
|
}
|
|
else
|
|
pNtk = pNtkTemp;
|
|
Abc_NtkMiterPrint( pNtk, "BDD building", clk, pParams->fVerbose );
|
|
}
|
|
#endif
|
|
|
|
if ( RetValue < 0 )
|
|
{
|
|
if ( pParams->fVerbose )
|
|
{
|
|
printf( "Attempting SAT with conflict limit %d ...\n", pParams->nMiteringLimitLast );
|
|
fflush( stdout );
|
|
}
|
|
clk = Abc_Clock();
|
|
nInspectLimit = pParams->nTotalInspectLimit? pParams->nTotalInspectLimit - pParams->nTotalInspectsMade : 0;
|
|
RetValue = Abc_NtkMiterSat( pNtk, (ABC_INT64_T)pParams->nMiteringLimitLast, (ABC_INT64_T)nInspectLimit, 0, NULL, NULL );
|
|
Abc_NtkMiterPrint( pNtk, "SAT solving", clk, pParams->fVerbose );
|
|
}
|
|
|
|
// assign the model if it was proved by rewriting (const 1 miter)
|
|
if ( RetValue == 0 && pNtk->pModel == NULL )
|
|
{
|
|
pNtk->pModel = ABC_ALLOC( int, Abc_NtkCiNum(pNtk) );
|
|
memset( pNtk->pModel, 0, sizeof(int) * Abc_NtkCiNum(pNtk) );
|
|
}
|
|
*ppNtk = pNtk;
|
|
return RetValue;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Attempts to solve the miter using a number of tricks.]
|
|
|
|
Description [Returns -1 if timed out; 0 if SAT; 1 if UNSAT.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Abc_Ntk_t * Abc_NtkMiterFraig( Abc_Ntk_t * pNtk, int nBTLimit, ABC_INT64_T nInspLimit, int * pRetValue, int * pNumFails, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects )
|
|
{
|
|
Abc_Ntk_t * pNtkNew;
|
|
Fraig_Params_t Params, * pParams = &Params;
|
|
Fraig_Man_t * pMan;
|
|
int nWords1, nWords2, nWordsMin, RetValue;
|
|
int * pModel;
|
|
|
|
// to determine the number of simulation patterns
|
|
// use the following strategy
|
|
// at least 64 words (32 words random and 32 words dynamic)
|
|
// no more than 256M for one circuit (128M + 128M)
|
|
nWords1 = 32;
|
|
nWords2 = (1<<27) / (Abc_NtkNodeNum(pNtk) + Abc_NtkCiNum(pNtk));
|
|
nWordsMin = Abc_MinInt( nWords1, nWords2 );
|
|
|
|
// set the FRAIGing parameters
|
|
Fraig_ParamsSetDefault( pParams );
|
|
pParams->nPatsRand = nWordsMin * 32; // the number of words of random simulation info
|
|
pParams->nPatsDyna = nWordsMin * 32; // the number of words of dynamic simulation info
|
|
pParams->nBTLimit = nBTLimit; // the max number of backtracks
|
|
pParams->nSeconds = -1; // the runtime limit
|
|
pParams->fTryProve = 0; // do not try to prove the final miter
|
|
pParams->fDoSparse = 1; // try proving sparse functions
|
|
pParams->fVerbose = 0;
|
|
pParams->nInspLimit = nInspLimit;
|
|
|
|
// transform the target into a fraig
|
|
pMan = (Fraig_Man_t *)Abc_NtkToFraig( pNtk, pParams, 0, 0 );
|
|
Fraig_ManProveMiter( pMan );
|
|
RetValue = Fraig_ManCheckMiter( pMan );
|
|
|
|
// create the network
|
|
pNtkNew = Abc_NtkFromFraig( pMan, pNtk );
|
|
|
|
// save model
|
|
if ( RetValue == 0 )
|
|
{
|
|
pModel = Fraig_ManReadModel( pMan );
|
|
ABC_FREE( pNtkNew->pModel );
|
|
pNtkNew->pModel = ABC_ALLOC( int, Abc_NtkCiNum(pNtkNew) );
|
|
memcpy( pNtkNew->pModel, pModel, sizeof(int) * Abc_NtkCiNum(pNtkNew) );
|
|
}
|
|
|
|
// save the return values
|
|
*pRetValue = RetValue;
|
|
*pNumFails = Fraig_ManReadSatFails( pMan );
|
|
*pNumConfs = Fraig_ManReadConflicts( pMan );
|
|
*pNumInspects = Fraig_ManReadInspects( pMan );
|
|
|
|
// delete the fraig manager
|
|
Fraig_ManFree( pMan );
|
|
return pNtkNew;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Attempts to solve the miter using a number of tricks.]
|
|
|
|
Description [Returns -1 if timed out; 0 if SAT; 1 if UNSAT.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Abc_NtkMiterPrint( Abc_Ntk_t * pNtk, char * pString, abctime clk, int fVerbose )
|
|
{
|
|
if ( !fVerbose )
|
|
return;
|
|
printf( "Nodes = %7d. Levels = %4d. ", Abc_NtkNodeNum(pNtk),
|
|
Abc_NtkIsStrash(pNtk)? Abc_AigLevel(pNtk) : Abc_NtkLevel(pNtk) );
|
|
ABC_PRT( pString, Abc_Clock() - clk );
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Implements resynthesis for CEC.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Abc_Ntk_t * Abc_NtkMiterRwsat( Abc_Ntk_t * pNtk )
|
|
{
|
|
Abc_Ntk_t * pNtkTemp;
|
|
Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 );
|
|
pNtk = Abc_NtkBalance( pNtkTemp = pNtk, 0, 0, 0 ); Abc_NtkDelete( pNtkTemp );
|
|
Abc_NtkRewrite( pNtk, 0, 0, 0, 0, 0 );
|
|
Abc_NtkRefactor( pNtk, 10, 16, 0, 0, 0, 0 );
|
|
return pNtk;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|