mirror of https://github.com/YosysHQ/abc.git
563 lines
20 KiB
C
563 lines
20 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [wlcAbs1.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Verilog parser.]
|
|
|
|
Synopsis [Abstraction for word-level networks.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - August 22, 2014.]
|
|
|
|
Revision [$Id: wlcAbs1.c,v 1.00 2014/09/12 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "wlc.h"
|
|
#include "proof/pdr/pdr.h"
|
|
#include "proof/pdr/pdrInt.h"
|
|
#include "aig/gia/giaAig.h"
|
|
#include "sat/bmc/bmc.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
extern Vec_Vec_t * IPdr_ManSaveClauses( Pdr_Man_t * p, int fDropLast );
|
|
extern int IPdr_ManRestore( Pdr_Man_t * p, Vec_Vec_t * vClauses );
|
|
extern int IPdr_ManSolveInt( Pdr_Man_t * p, int fCheckClauses, int fPushClauses );
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Mark operators that meet the abstraction criteria.]
|
|
|
|
Description [This procedure returns the array of objects (vLeaves) that
|
|
should be abstracted because of their high bit-width. It uses input array (vUnmark)
|
|
to not abstract those objects that have been refined in the previous rounds.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose )
|
|
{
|
|
Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) );
|
|
Wlc_Obj_t * pObj; int i, Count[4] = {0};
|
|
Wlc_NtkForEachObj( p, pObj, i )
|
|
{
|
|
if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away
|
|
continue;
|
|
if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
|
|
{
|
|
if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
|
|
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++;
|
|
continue;
|
|
}
|
|
if ( pObj->Type == WLC_OBJ_ARI_MULTI || pObj->Type == WLC_OBJ_ARI_DIVIDE || pObj->Type == WLC_OBJ_ARI_REM || pObj->Type == WLC_OBJ_ARI_MODULUS )
|
|
{
|
|
if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
|
|
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++;
|
|
continue;
|
|
}
|
|
if ( pObj->Type == WLC_OBJ_MUX )
|
|
{
|
|
if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
|
|
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++;
|
|
continue;
|
|
}
|
|
if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
|
|
{
|
|
if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
|
|
Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++;
|
|
continue;
|
|
}
|
|
}
|
|
if ( fVerbose )
|
|
printf( "Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away.\n", Count[0], Count[1], Count[2], Count[3] );
|
|
return vLeaves;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Marks nodes to be included in the abstracted network.]
|
|
|
|
Description [Marks all objects that will be included in the abstracted model.
|
|
Stops at the objects (vLeaves) that are abstracted away. Returns three arrays:
|
|
a subset of original PIs (vPisOld), a subset of pseudo-PIs (vPisNew) and the
|
|
set of flops present as flops in the abstracted network.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static void Wlc_NtkAbsMarkNodes_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pObj, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
|
|
{
|
|
int i, iFanin;
|
|
if ( pObj->Mark )
|
|
return;
|
|
pObj->Mark = 1;
|
|
if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) )
|
|
{
|
|
assert( !Wlc_ObjIsPi(pObj) );
|
|
Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) );
|
|
return;
|
|
}
|
|
if ( Wlc_ObjIsCi(pObj) )
|
|
{
|
|
if ( Wlc_ObjIsPi(pObj) )
|
|
Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) );
|
|
else
|
|
Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
|
|
return;
|
|
}
|
|
Wlc_ObjForEachFanin( pObj, iFanin, i )
|
|
Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops );
|
|
}
|
|
static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
|
|
{
|
|
Wlc_Obj_t * pObj;
|
|
int i, Count = 0;
|
|
Wlc_NtkCleanMarks( p );
|
|
Wlc_NtkForEachCo( p, pObj, i )
|
|
Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops );
|
|
|
|
|
|
Vec_IntClear(vFlops);
|
|
Wlc_NtkForEachCi( p, pObj, i ) {
|
|
if ( !Wlc_ObjIsPi(pObj) ) {
|
|
Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
|
|
pObj->Mark = 1;
|
|
}
|
|
}
|
|
|
|
|
|
Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
|
|
Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops );
|
|
Wlc_NtkForEachObj( p, pObj, i )
|
|
Count += pObj->Mark;
|
|
// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n",
|
|
// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops),
|
|
// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) );
|
|
Vec_IntSort( vPisOld, 0 );
|
|
Vec_IntSort( vPisNew, 0 );
|
|
Vec_IntSort( vFlops, 0 );
|
|
Wlc_NtkCleanMarks( p );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Derive word-level abstracted model based on the parameter values.]
|
|
|
|
Description [Retuns the word-level abstracted network and the set of pseudo-PIs
|
|
(vPisNew), which were created during abstraction. If the abstraction is
|
|
satisfiable, some of the pseudo-PIs will be un-abstracted. These pseudo-PIs
|
|
and their MFFC cones will be listed in the array (vUnmark), which will
|
|
force the abstraction to not stop at these pseudo-PIs in the future.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose )
|
|
{
|
|
Wlc_Ntk_t * pNtkNew = NULL;
|
|
Vec_Int_t * vPisOld = Vec_IntAlloc( 100 );
|
|
Vec_Int_t * vPisNew = Vec_IntAlloc( 100 );
|
|
Vec_Int_t * vFlops = Vec_IntAlloc( 100 );
|
|
Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose );
|
|
Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops );
|
|
Vec_BitFree( vLeaves );
|
|
pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops );
|
|
Vec_IntFree( vPisOld );
|
|
Vec_IntFree( vFlops );
|
|
if ( pvPisNew )
|
|
*pvPisNew = vPisNew;
|
|
else
|
|
Vec_IntFree( vPisNew );
|
|
return pNtkNew;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Find what objects need to be un-abstracted.]
|
|
|
|
Description [Returns a subset of pseudo-PIs (vPisNew), which will be
|
|
prevented from being abstracted in the future rounds of abstraction.
|
|
The AIG manager (pGia) is a bit-level view of the abstracted model.
|
|
The counter-example (pCex) is used to find waht PPIs to refine.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew )
|
|
{
|
|
Vec_Int_t * vRefine = Vec_IntAlloc( 100 );
|
|
Abc_Cex_t * pCexCare;
|
|
Wlc_Obj_t * pObj;
|
|
// count the number of bit-level PPIs and map them into word-level objects they were derived from
|
|
int f, i, b, nRealPis, nPpiBits = 0;
|
|
Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis );
|
|
Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
|
|
for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
|
|
Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) );
|
|
// since PPIs are ordered last, the previous bits are real PIs
|
|
nRealPis = pCex->nPis - nPpiBits;
|
|
// find the care-set
|
|
pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 );
|
|
assert( pCexCare->nPis == pCex->nPis );
|
|
// detect care PPIs
|
|
for ( f = 0; f <= pCexCare->iFrame; f++ )
|
|
for ( i = nRealPis; i < pCexCare->nPis; i++ )
|
|
if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
|
|
Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) );
|
|
Abc_CexFree( pCexCare );
|
|
Vec_IntFree( vMap );
|
|
if ( Vec_IntSize(vRefine) == 0 )// real CEX
|
|
Vec_IntFreeP( &vRefine );
|
|
return vRefine;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Mark MFFC cones of the un-abstracted objects.]
|
|
|
|
Description [The MFFC cones of the objects in vRefine are traversed
|
|
and all their nodes are marked in vUnmark.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
|
|
{
|
|
int i, Fanin, Counter = 1;
|
|
if ( Wlc_ObjIsCi(pNode) )
|
|
return 0;
|
|
Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
|
|
Wlc_ObjForEachFanin( pNode, Fanin, i )
|
|
{
|
|
Vec_IntAddToEntry( &p->vRefs, Fanin, -1 );
|
|
if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
|
|
Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark );
|
|
}
|
|
return Counter;
|
|
}
|
|
static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode )
|
|
{
|
|
int i, Fanin, Counter = 1;
|
|
if ( Wlc_ObjIsCi(pNode) )
|
|
return 0;
|
|
Wlc_ObjForEachFanin( pNode, Fanin, i )
|
|
{
|
|
if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
|
|
Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) );
|
|
Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
|
|
}
|
|
return Counter;
|
|
}
|
|
static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
|
|
{
|
|
int Count1, Count2;
|
|
// if this is a flop output, compute MFFC of the corresponding flop input
|
|
while ( Wlc_ObjIsCi(pNode) )
|
|
{
|
|
Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
|
|
pNode = Wlc_ObjFo2Fi(p, pNode);
|
|
}
|
|
assert( !Wlc_ObjIsCi(pNode) );
|
|
// dereference the node (and set the bits in vUnmark)
|
|
Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark );
|
|
// reference it back
|
|
Count2 = Wlc_NtkNodeRef_rec( p, pNode );
|
|
assert( Count1 == Count2 );
|
|
return Count1;
|
|
}
|
|
static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark )
|
|
{
|
|
Wlc_Obj_t * pObj; int i, nNodes = 0;
|
|
if ( Vec_IntSize(&p->vRefs) == 0 )
|
|
Wlc_NtkSetRefs( p );
|
|
Wlc_NtkForEachObjVec( vRefine, p, pObj, i )
|
|
nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark );
|
|
return nNodes;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Performs PDR with word-level abstraction.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Wlc_NtkPdrAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
|
|
{
|
|
abctime clk = Abc_Clock();
|
|
abctime pdrClk;
|
|
Pdr_Man_t * pPdr;
|
|
Vec_Vec_t * vClauses = NULL;
|
|
int nIters, nNodes, nDcFlops, RetValue = -1;
|
|
// start the bitmap to mark objects that cannot be abstracted because of refinement
|
|
// currently, this bitmap is empty because abstraction begins without refinement
|
|
Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
|
|
// set up parameters to run PDR
|
|
Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
|
|
Pdr_ManSetDefaultParams( pPdrPars );
|
|
pPdrPars->fVerbose = pPars->fPdrVerbose;
|
|
pPdrPars->fVeryVerbose = 0;
|
|
|
|
// perform refinement iterations
|
|
for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
|
|
{
|
|
Aig_Man_t * pAig;
|
|
Abc_Cex_t * pCex;
|
|
Vec_Int_t * vPisNew, * vRefine;
|
|
Gia_Man_t * pGia, * pTemp;
|
|
Wlc_Ntk_t * pAbs;
|
|
|
|
if ( pPars->fVerbose )
|
|
printf( "\nIteration %d:\n", nIters );
|
|
|
|
// get abstracted GIA and the set of pseudo-PIs (vPisNew)
|
|
pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose );
|
|
pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
|
|
|
|
// if the abstraction has flops with DC-init state,
|
|
// new PIs were introduced by bit-blasting at the end of the PI list
|
|
// here we move these variables to be *before* PPIs, because
|
|
// PPIs are supposed to be at the end of the PI list for refinement
|
|
nDcFlops = Wlc_NtkDcFlopNum(pAbs);
|
|
if ( nDcFlops > 0 ) // DC-init flops are present
|
|
{
|
|
pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
|
|
Gia_ManStop( pTemp );
|
|
}
|
|
// if the word-level outputs have to be XORs, this is a place to do it
|
|
if ( pPars->fXorOutput )
|
|
{
|
|
pGia = Gia_ManTransformMiter2( pTemp = pGia );
|
|
Gia_ManStop( pTemp );
|
|
}
|
|
if ( pPars->fVerbose )
|
|
{
|
|
printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
|
|
Gia_ManPrintStats( pGia, NULL );
|
|
}
|
|
Wlc_NtkFree( pAbs );
|
|
|
|
// try to prove abstracted GIA by converting it to AIG and calling PDR
|
|
pAig = Gia_ManToAigSimple( pGia );
|
|
|
|
pPdr = Pdr_ManStart( pAig, pPdrPars, NULL );
|
|
pdrClk = Abc_Clock();
|
|
|
|
if ( vClauses ) {
|
|
assert( Vec_VecSize( vClauses) >= 2 );
|
|
IPdr_ManRestore( pPdr, vClauses );
|
|
}
|
|
|
|
RetValue = IPdr_ManSolveInt( pPdr, pPars->fCheckClauses, pPars->fPushClauses );
|
|
pPdr->tTotal += Abc_Clock() - pdrClk;
|
|
|
|
pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
|
|
|
|
// consider outcomes
|
|
if ( pCex == NULL )
|
|
{
|
|
assert( RetValue ); // proved or undecided
|
|
Gia_ManStop( pGia );
|
|
Vec_IntFree( vPisNew );
|
|
Pdr_ManStop( pPdr );
|
|
Aig_ManStop( pAig );
|
|
break;
|
|
}
|
|
|
|
// perform refinement
|
|
vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
|
|
Gia_ManStop( pGia );
|
|
Vec_IntFree( vPisNew );
|
|
if ( vRefine == NULL ) // real CEX
|
|
{
|
|
Abc_CexFree( pCex ); // return CEX in the future
|
|
Pdr_ManStop( pPdr );
|
|
Aig_ManStop( pAig );
|
|
break;
|
|
}
|
|
|
|
// spurious CEX, continue solving
|
|
vClauses = IPdr_ManSaveClauses( pPdr, 0 );
|
|
|
|
Pdr_ManStop( pPdr );
|
|
|
|
// update the set of objects to be un-abstracted
|
|
nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
|
|
if ( pPars->fVerbose )
|
|
printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
|
|
Vec_IntFree( vRefine );
|
|
Abc_CexFree( pCex );
|
|
Aig_ManStop( pAig );
|
|
}
|
|
|
|
Vec_BitFree( vUnmark );
|
|
// report the result
|
|
if ( pPars->fVerbose )
|
|
printf( "\n" );
|
|
printf( "Abstraction " );
|
|
if ( RetValue == 0 )
|
|
printf( "resulted in a real CEX" );
|
|
else if ( RetValue == 1 )
|
|
printf( "is successfully proved" );
|
|
else
|
|
printf( "timed out" );
|
|
printf( " after %d iterations. ", nIters );
|
|
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
|
return RetValue;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Performs abstraction.]
|
|
|
|
Description [Derives initial abstraction based on user-specified
|
|
parameter values, which tell what is the smallest bit-width of a
|
|
primitive that is being abstracted away. Currently only add/sub,
|
|
mul/div, mux, and flop are supported with individual parameters.
|
|
The second step is to refine the initial abstraction until the
|
|
point when the property is proved.]
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Wlc_NtkAbsCore( Wlc_Ntk_t * p, Wlc_Par_t * pPars )
|
|
{
|
|
abctime clk = Abc_Clock();
|
|
int nIters, nNodes, nDcFlops, RetValue = -1;
|
|
// start the bitmap to mark objects that cannot be abstracted because of refinement
|
|
// currently, this bitmap is empty because abstraction begins without refinement
|
|
Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
|
|
// set up parameters to run PDR
|
|
Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
|
|
Pdr_ManSetDefaultParams( pPdrPars );
|
|
//pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction)
|
|
//pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization)
|
|
//pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization)
|
|
//pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
|
|
pPdrPars->fVerbose = pPars->fPdrVerbose;
|
|
pPdrPars->fVeryVerbose = 0;
|
|
// perform refinement iterations
|
|
for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
|
|
{
|
|
Aig_Man_t * pAig;
|
|
Abc_Cex_t * pCex;
|
|
Vec_Int_t * vPisNew, * vRefine;
|
|
Gia_Man_t * pGia, * pTemp;
|
|
Wlc_Ntk_t * pAbs;
|
|
|
|
if ( pPars->fVerbose )
|
|
printf( "\nIteration %d:\n", nIters );
|
|
|
|
// get abstracted GIA and the set of pseudo-PIs (vPisNew)
|
|
pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose );
|
|
pGia = Wlc_NtkBitBlast( pAbs, NULL, -1, 0, 0, 0, 0 );
|
|
|
|
// if the abstraction has flops with DC-init state,
|
|
// new PIs were introduced by bit-blasting at the end of the PI list
|
|
// here we move these variables to be *before* PPIs, because
|
|
// PPIs are supposed to be at the end of the PI list for refinement
|
|
nDcFlops = Wlc_NtkDcFlopNum(pAbs);
|
|
if ( nDcFlops > 0 ) // DC-init flops are present
|
|
{
|
|
pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
|
|
Gia_ManStop( pTemp );
|
|
}
|
|
// if the word-level outputs have to be XORs, this is a place to do it
|
|
if ( pPars->fXorOutput )
|
|
{
|
|
pGia = Gia_ManTransformMiter2( pTemp = pGia );
|
|
Gia_ManStop( pTemp );
|
|
}
|
|
if ( pPars->fVerbose )
|
|
{
|
|
printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
|
|
Gia_ManPrintStats( pGia, NULL );
|
|
}
|
|
Wlc_NtkFree( pAbs );
|
|
|
|
// try to prove abstracted GIA by converting it to AIG and calling PDR
|
|
pAig = Gia_ManToAigSimple( pGia );
|
|
RetValue = Pdr_ManSolve( pAig, pPdrPars );
|
|
pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
|
|
Aig_ManStop( pAig );
|
|
|
|
// consider outcomes
|
|
if ( pCex == NULL )
|
|
{
|
|
assert( RetValue ); // proved or undecided
|
|
Gia_ManStop( pGia );
|
|
Vec_IntFree( vPisNew );
|
|
break;
|
|
}
|
|
|
|
// perform refinement
|
|
vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
|
|
Gia_ManStop( pGia );
|
|
Vec_IntFree( vPisNew );
|
|
if ( vRefine == NULL ) // real CEX
|
|
{
|
|
Abc_CexFree( pCex ); // return CEX in the future
|
|
break;
|
|
}
|
|
|
|
// update the set of objects to be un-abstracted
|
|
nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
|
|
if ( pPars->fVerbose )
|
|
printf( "Refinement of CEX in frame %d came up with %d un-abstacted PPIs, whose MFFCs include %d objects.\n", pCex->iFrame, Vec_IntSize(vRefine), nNodes );
|
|
Vec_IntFree( vRefine );
|
|
Abc_CexFree( pCex );
|
|
}
|
|
Vec_BitFree( vUnmark );
|
|
// report the result
|
|
if ( pPars->fVerbose )
|
|
printf( "\n" );
|
|
printf( "Abstraction " );
|
|
if ( RetValue == 0 )
|
|
printf( "resulted in a real CEX" );
|
|
else if ( RetValue == 1 )
|
|
printf( "is successfully proved" );
|
|
else
|
|
printf( "timed out" );
|
|
printf( " after %d iterations. ", nIters );
|
|
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
|
return RetValue;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|