2014-11-15 05:12:20 +01:00
/**CFile****************************************************************
2017-02-22 07:20:03 +01:00
FileName [ wlcAbs . c ]
2014-11-15 05:12:20 +01:00
SystemName [ ABC : Logic synthesis and verification system . ]
PackageName [ Verilog parser . ]
Synopsis [ Abstraction for word - level networks . ]
2017-02-22 07:20:03 +01:00
Author [ Yen - Sheng Ho , Alan Mishchenko ]
2014-11-15 05:12:20 +01:00
Affiliation [ UC Berkeley ]
Date [ Ver . 1.0 . Started - August 22 , 2014. ]
2017-02-22 07:20:03 +01:00
Revision [ $ Id : wlcAbs . c , v 1.00 2014 / 09 / 12 00 : 00 : 00 alanmi Exp $ ]
2014-11-15 05:12:20 +01:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "wlc.h"
2017-02-16 02:16:19 +01:00
# include "proof/pdr/pdr.h"
2017-02-19 19:22:15 +01:00
# include "proof/pdr/pdrInt.h"
2017-03-03 07:16:16 +01:00
# include "proof/ssw/ssw.h"
2017-02-16 02:16:19 +01:00
# include "aig/gia/giaAig.h"
# include "sat/bmc/bmc.h"
2014-11-15 05:12:20 +01:00
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
2017-02-19 19:22:15 +01:00
extern Vec_Vec_t * IPdr_ManSaveClauses ( Pdr_Man_t * p , int fDropLast ) ;
2017-02-22 07:20:03 +01:00
extern int IPdr_ManRestore ( Pdr_Man_t * p , Vec_Vec_t * vClauses , Vec_Int_t * vMap ) ;
2017-02-20 21:51:04 +01:00
extern int IPdr_ManSolveInt ( Pdr_Man_t * p , int fCheckClauses , int fPushClauses ) ;
2017-03-01 23:57:43 +01:00
extern int IPdr_ManCheckCombUnsat ( Pdr_Man_t * p ) ;
2017-03-03 02:31:30 +01:00
extern int IPdr_ManReduceClauses ( Pdr_Man_t * p , Vec_Vec_t * vClauses ) ;
extern void IPdr_ManPrintClauses ( Vec_Vec_t * vClauses , int kStart , int nRegs ) ;
2017-02-19 19:22:15 +01:00
2017-02-27 00:39:48 +01:00
typedef struct Int_Pair_t_ Int_Pair_t ;
struct Int_Pair_t_
{
int first ;
int second ;
} ;
int IntPairPtrCompare ( Int_Pair_t * * a , Int_Pair_t * * b )
{
return ( * a ) - > second < ( * b ) - > second ;
}
2014-11-15 05:12:20 +01:00
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
2017-02-25 23:58:01 +01:00
int Wlc_NtkNumPiBits ( Wlc_Ntk_t * pNtk )
{
int num = 0 ;
int i ;
Wlc_Obj_t * pObj ;
Wlc_NtkForEachPi ( pNtk , pObj , i ) {
num + = Wlc_ObjRange ( pObj ) ;
}
return num ;
}
2017-02-26 07:26:51 +01:00
static Vec_Int_t * Wlc_NtkGetCoreSels ( Gia_Man_t * pFrames , int nFrames , int num_sel_pis , int num_other_pis , Vec_Bit_t * vMark , int sel_pi_first , int nConfLimit , Wlc_Par_t * pPars )
2017-02-26 00:22:30 +01:00
{
Vec_Int_t * vCores = NULL ;
Aig_Man_t * pAigFrames = Gia_ManToAigSimple ( pFrames ) ;
Cnf_Dat_t * pCnf = Cnf_Derive ( pAigFrames , Aig_ManCoNum ( pAigFrames ) ) ;
sat_solver * pSat = sat_solver_new ( ) ;
2017-03-01 05:15:33 +01:00
int i ;
2017-02-26 00:22:30 +01:00
sat_solver_setnvars ( pSat , pCnf - > nVars ) ;
2017-03-01 05:15:33 +01:00
for ( i = 0 ; i < pCnf - > nClauses ; i + + )
2017-02-26 00:22:30 +01:00
{
if ( ! sat_solver_addclause ( pSat , pCnf - > pClauses [ i ] , pCnf - > pClauses [ i + 1 ] ) )
assert ( false ) ;
}
// add PO clauses
{
Vec_Int_t * vLits = Vec_IntAlloc ( 100 ) ;
Aig_Obj_t * pObj ;
int i , ret ;
Aig_ManForEachCo ( pAigFrames , pObj , i )
{
assert ( pCnf - > pVarNums [ pObj - > Id ] > = 0 ) ;
Vec_IntPush ( vLits , toLitCond ( pCnf - > pVarNums [ pObj - > Id ] , 0 ) ) ;
}
ret = sat_solver_addclause ( pSat , Vec_IntArray ( vLits ) , Vec_IntArray ( vLits ) + Vec_IntSize ( vLits ) ) ;
if ( ! ret )
Abc_Print ( 1 , " UNSAT after adding PO clauses. \n " ) ;
Vec_IntFree ( vLits ) ;
}
// main procedure
{
2017-03-01 05:15:33 +01:00
int status ;
2017-02-26 00:22:30 +01:00
Vec_Int_t * vLits = Vec_IntAlloc ( 100 ) ;
Vec_Int_t * vMapVar2Sel = Vec_IntStart ( pCnf - > nVars ) ;
int first_sel_pi = sel_pi_first ? 0 : num_other_pis ;
2017-03-01 05:15:33 +01:00
for ( i = 0 ; i < num_sel_pis ; + + i )
2017-02-26 00:22:30 +01:00
{
int cur_pi = first_sel_pi + i ;
int var = pCnf - > pVarNums [ Aig_ManCi ( pAigFrames , cur_pi ) - > Id ] ;
2017-02-26 07:26:51 +01:00
int Lit ;
2017-02-26 00:22:30 +01:00
assert ( var > = 0 ) ;
Vec_IntWriteEntry ( vMapVar2Sel , var , i ) ;
2017-02-26 07:26:51 +01:00
Lit = toLitCond ( var , 0 ) ;
if ( Vec_BitEntry ( vMark , i ) )
Vec_IntPush ( vLits , Lit ) ;
else
sat_solver_addclause ( pSat , & Lit , & Lit + 1 ) ;
2017-02-26 00:22:30 +01:00
}
2017-02-26 03:32:43 +01:00
/*
2017-02-26 00:22:30 +01:00
int i , Entry ;
Abc_Print ( 1 , " #vLits = %d; vLits = " , Vec_IntSize ( vLits ) ) ;
Vec_IntForEachEntry ( vLits , Entry , i )
Abc_Print ( 1 , " %d " , Entry ) ;
2017-02-26 03:32:43 +01:00
Abc_Print ( 1 , " \n " ) ;
*/
2017-03-01 05:15:33 +01:00
status = sat_solver_solve ( pSat , Vec_IntArray ( vLits ) , Vec_IntArray ( vLits ) + Vec_IntSize ( vLits ) , ( ABC_INT64_T ) ( nConfLimit ) , ( ABC_INT64_T ) ( 0 ) , ( ABC_INT64_T ) ( 0 ) , ( ABC_INT64_T ) ( 0 ) ) ;
2017-02-26 00:22:30 +01:00
if ( status = = l_False ) {
int nCoreLits , * pCoreLits ;
2017-03-01 05:15:33 +01:00
Abc_Print ( 1 , " UNSAT. \n " ) ;
2017-02-26 00:22:30 +01:00
nCoreLits = sat_solver_final ( pSat , & pCoreLits ) ;
vCores = Vec_IntAlloc ( nCoreLits ) ;
2017-03-01 05:15:33 +01:00
for ( i = 0 ; i < nCoreLits ; i + + )
2017-02-26 00:22:30 +01:00
{
Vec_IntPush ( vCores , Vec_IntEntry ( vMapVar2Sel , lit_var ( pCoreLits [ i ] ) ) ) ;
}
} else if ( status = = l_True ) {
Abc_Print ( 1 , " SAT. \n " ) ;
} else {
Abc_Print ( 1 , " UNKNOWN. \n " ) ;
}
Vec_IntFree ( vLits ) ;
Vec_IntFree ( vMapVar2Sel ) ;
}
Cnf_ManFree ( ) ;
sat_solver_delete ( pSat ) ;
Aig_ManStop ( pAigFrames ) ;
return vCores ;
}
2017-03-10 06:43:18 +01:00
static Gia_Man_t * Wlc_NtkUnrollWithCex ( Wlc_Ntk_t * pChoice , Abc_Cex_t * pCex , int nbits_old_pis , int num_sel_pis , int * p_num_ppis , int sel_pi_first , int fUsePPI )
2017-02-25 23:58:01 +01:00
{
Gia_Man_t * pGiaChoice = Wlc_NtkBitBlast ( pChoice , NULL , - 1 , 0 , 0 , 0 , 0 ) ;
int nbits_new_pis = Wlc_NtkNumPiBits ( pChoice ) ;
int num_ppis = nbits_new_pis - nbits_old_pis - num_sel_pis ;
int num_undc_pis = Gia_ManPiNum ( pGiaChoice ) - nbits_new_pis ;
Gia_Man_t * pFrames = NULL ;
Gia_Obj_t * pObj , * pObjRi ;
int f , i ;
int is_sel_pi ;
Gia_Man_t * pGia ;
2017-03-01 05:15:33 +01:00
* p_num_ppis = num_ppis ;
2017-02-25 23:58:01 +01:00
Abc_Print ( 1 , " #orig_pis = %d, #ppis = %d, #sel_pis = %d, #undc_pis = %d \n " , nbits_old_pis , num_ppis , num_sel_pis , num_undc_pis ) ;
assert ( Gia_ManPiNum ( pGiaChoice ) = = nbits_old_pis + num_ppis + num_sel_pis + num_undc_pis ) ;
assert ( Gia_ManPiNum ( pGiaChoice ) = = pCex - > nPis + num_sel_pis ) ;
pFrames = Gia_ManStart ( 10000 ) ;
pFrames - > pName = Abc_UtilStrsav ( pGiaChoice - > pName ) ;
Gia_ManHashAlloc ( pFrames ) ;
Gia_ManConst0 ( pGiaChoice ) - > Value = 0 ;
Gia_ManForEachRi ( pGiaChoice , pObj , i )
pObj - > Value = 0 ;
for ( f = 0 ; f < = pCex - > iFrame ; f + + )
{
for ( i = 0 ; i < Gia_ManPiNum ( pGiaChoice ) ; i + + )
{
if ( i > = nbits_old_pis & & i < nbits_old_pis + num_ppis + num_sel_pis )
{
is_sel_pi = sel_pi_first ? ( i < nbits_old_pis + num_sel_pis ) : ( i > = nbits_old_pis + num_ppis ) ;
2017-03-10 06:43:18 +01:00
if ( f = = 0 & & is_sel_pi )
2017-02-25 23:58:01 +01:00
Gia_ManPi ( pGiaChoice , i ) - > Value = Gia_ManAppendCi ( pFrames ) ;
2017-03-10 06:43:18 +01:00
if ( ! is_sel_pi )
{
if ( ! fUsePPI )
Gia_ManPi ( pGiaChoice , i ) - > Value = Gia_ManAppendCi ( pFrames ) ;
else
Gia_ManPi ( pGiaChoice , i ) - > Value = Abc_InfoHasBit ( pCex - > pData , pCex - > nRegs + pCex - > nPis * f + i + num_undc_pis ) ;
}
2017-02-25 23:58:01 +01:00
}
else if ( i < nbits_old_pis )
{
Gia_ManPi ( pGiaChoice , i ) - > Value = Abc_InfoHasBit ( pCex - > pData , pCex - > nRegs + pCex - > nPis * f + i ) ;
}
else if ( i > = nbits_old_pis + num_ppis + num_sel_pis )
{
2017-02-26 03:32:43 +01:00
Gia_ManPi ( pGiaChoice , i ) - > Value = Abc_InfoHasBit ( pCex - > pData , pCex - > nRegs + pCex - > nPis * f + i - num_sel_pis - num_ppis ) ;
2017-02-25 23:58:01 +01:00
}
}
Gia_ManForEachRiRo ( pGiaChoice , pObjRi , pObj , i )
pObj - > Value = pObjRi - > Value ;
Gia_ManForEachAnd ( pGiaChoice , pObj , i )
pObj - > Value = Gia_ManHashAnd ( pFrames , Gia_ObjFanin0Copy ( pObj ) , Gia_ObjFanin1Copy ( pObj ) ) ;
Gia_ManForEachCo ( pGiaChoice , pObj , i )
pObj - > Value = Gia_ObjFanin0Copy ( pObj ) ;
Gia_ManForEachPo ( pGiaChoice , pObj , i )
Gia_ManAppendCo ( pFrames , pObj - > Value ) ;
}
Gia_ManHashStop ( pFrames ) ;
Gia_ManSetRegNum ( pFrames , 0 ) ;
pFrames = Gia_ManCleanup ( pGia = pFrames ) ;
Gia_ManStop ( pGia ) ;
Gia_ManStop ( pGiaChoice ) ;
return pFrames ;
}
2017-02-26 03:32:43 +01:00
Wlc_Ntk_t * Wlc_NtkIntroduceChoices ( Wlc_Ntk_t * pNtk , Vec_Int_t * vBlacks )
2017-02-25 18:37:59 +01:00
{
2017-03-01 05:15:33 +01:00
//if ( vBlacks== NULL ) return NULL;
2017-02-26 03:32:43 +01:00
Vec_Int_t * vNodes = Vec_IntDup ( vBlacks ) ;
2017-02-25 18:37:59 +01:00
Wlc_Ntk_t * pNew ;
Wlc_Obj_t * pObj ;
int i , k , iObj , iFanin ;
Vec_Int_t * vFanins = Vec_IntAlloc ( 3 ) ;
2017-02-26 03:32:43 +01:00
Vec_Int_t * vMapNode2Pi = Vec_IntStart ( Wlc_NtkObjNumMax ( pNtk ) ) ;
Vec_Int_t * vMapNode2Sel = Vec_IntStart ( Wlc_NtkObjNumMax ( pNtk ) ) ;
2017-02-25 18:37:59 +01:00
int nOrigObjNum = Wlc_NtkObjNumMax ( pNtk ) ;
2017-02-26 03:32:43 +01:00
Wlc_Ntk_t * p = Wlc_NtkDupDfsSimple ( pNtk ) ;
2017-02-25 18:37:59 +01:00
Wlc_NtkForEachObjVec ( vNodes , pNtk , pObj , i )
{
// TODO : fix FOs here
Vec_IntWriteEntry ( vNodes , i , Wlc_ObjCopy ( pNtk , Wlc_ObjId ( pNtk , pObj ) ) ) ;
}
// Vec_IntPrint(vNodes);
Wlc_NtkCleanCopy ( p ) ;
// mark nodes
Wlc_NtkForEachObjVec ( vNodes , p , pObj , i )
{
iObj = Wlc_ObjId ( p , pObj ) ;
pObj - > Mark = 1 ;
// add fresh PI with the same number of bits
Vec_IntWriteEntry ( vMapNode2Pi , iObj , Wlc_ObjAlloc ( p , WLC_OBJ_PI , Wlc_ObjIsSigned ( pObj ) , Wlc_ObjRange ( pObj ) - 1 , 0 ) ) ;
}
2017-02-26 03:32:43 +01:00
// add sel PI
Wlc_NtkForEachObjVec ( vNodes , p , pObj , i )
{
iObj = Wlc_ObjId ( p , pObj ) ;
Vec_IntWriteEntry ( vMapNode2Sel , iObj , Wlc_ObjAlloc ( p , WLC_OBJ_PI , 0 , 0 , 0 ) ) ;
}
2017-02-25 18:37:59 +01:00
// iterate through the nodes in the DFS order
Wlc_NtkForEachObj ( p , pObj , i )
{
2017-02-26 03:32:43 +01:00
int isSigned , range ;
2017-02-25 18:37:59 +01:00
if ( i = = nOrigObjNum )
{
// cout << "break at " << i << endl;
break ;
}
if ( pObj - > Mark )
{
// clean
pObj - > Mark = 0 ;
isSigned = Wlc_ObjIsSigned ( pObj ) ;
range = Wlc_ObjRange ( pObj ) ;
Vec_IntClear ( vFanins ) ;
2017-02-26 03:32:43 +01:00
Vec_IntPush ( vFanins , Vec_IntEntry ( vMapNode2Sel , i ) ) ;
2017-02-25 18:37:59 +01:00
Vec_IntPush ( vFanins , Vec_IntEntry ( vMapNode2Pi , i ) ) ;
Vec_IntPush ( vFanins , i ) ;
iObj = Wlc_ObjCreate ( p , WLC_OBJ_MUX , isSigned , range - 1 , 0 , vFanins ) ;
}
else
{
// update fanins
Wlc_ObjForEachFanin ( pObj , iFanin , k )
Wlc_ObjFanins ( pObj ) [ k ] = Wlc_ObjCopy ( p , iFanin ) ;
// node to remain
iObj = i ;
}
Wlc_ObjSetCopy ( p , i , iObj ) ;
}
Wlc_NtkForEachCo ( p , pObj , i )
{
iObj = Wlc_ObjId ( p , pObj ) ;
if ( iObj ! = Wlc_ObjCopy ( p , iObj ) )
{
if ( pObj - > fIsFi )
Wlc_NtkObj ( p , Wlc_ObjCopy ( p , iObj ) ) - > fIsFi = 1 ;
else
Wlc_NtkObj ( p , Wlc_ObjCopy ( p , iObj ) ) - > fIsPo = 1 ;
Vec_IntWriteEntry ( & p - > vCos , i , Wlc_ObjCopy ( p , iObj ) ) ;
}
}
// DumpWlcNtk(p);
2017-02-26 03:32:43 +01:00
pNew = Wlc_NtkDupDfsSimple ( p ) ;
2017-02-25 18:37:59 +01:00
Vec_IntFree ( vFanins ) ;
Vec_IntFree ( vMapNode2Pi ) ;
2017-02-26 03:32:43 +01:00
Vec_IntFree ( vMapNode2Sel ) ;
Vec_IntFree ( vNodes ) ;
2017-02-25 18:37:59 +01:00
Wlc_NtkFree ( p ) ;
return pNew ;
}
2017-03-01 21:12:42 +01:00
static int Wlc_NtkCexIsReal ( Wlc_Ntk_t * pOrig , Abc_Cex_t * pCex )
{
Gia_Man_t * pGiaOrig = Wlc_NtkBitBlast ( pOrig , NULL , - 1 , 0 , 0 , 0 , 0 ) ;
int f , i ;
Gia_Obj_t * pObj , * pObjRi ;
Gia_ManConst0 ( pGiaOrig ) - > Value = 0 ;
Gia_ManForEachRi ( pGiaOrig , pObj , i )
pObj - > Value = 0 ;
for ( f = 0 ; f < = pCex - > iFrame ; f + + )
{
for ( i = 0 ; i < Gia_ManPiNum ( pGiaOrig ) ; i + + )
Gia_ManPi ( pGiaOrig , i ) - > Value = Abc_InfoHasBit ( pCex - > pData , pCex - > nRegs + pCex - > nPis * f + i ) ;
Gia_ManForEachRiRo ( pGiaOrig , pObjRi , pObj , i )
pObj - > Value = pObjRi - > Value ;
Gia_ManForEachAnd ( pGiaOrig , pObj , i )
pObj - > Value = Gia_ObjFanin0Copy ( pObj ) & Gia_ObjFanin1Copy ( pObj ) ;
Gia_ManForEachCo ( pGiaOrig , pObj , i )
pObj - > Value = Gia_ObjFanin0Copy ( pObj ) ;
Gia_ManForEachPo ( pGiaOrig , pObj , i )
{
if ( pObj - > Value = = 1 ) {
Abc_Print ( 1 , " CEX is real on the original model. \n " ) ;
Gia_ManStop ( pGiaOrig ) ;
return 1 ;
}
}
}
// Abc_Print( 1, "CEX is spurious.\n" );
Gia_ManStop ( pGiaOrig ) ;
return 0 ;
}
2017-02-26 03:32:43 +01:00
static Wlc_Ntk_t * Wlc_NtkAbs2 ( Wlc_Ntk_t * pNtk , Vec_Int_t * vBlacks , Vec_Int_t * * pvFlops )
{
Vec_Int_t * vFlops = Vec_IntAlloc ( 100 ) ;
Vec_Int_t * vNodes = Vec_IntDup ( vBlacks ) ;
Wlc_Ntk_t * pNew ;
Wlc_Obj_t * pObj ;
int i , k , iObj , iFanin ;
Vec_Int_t * vMapNode2Pi = Vec_IntStart ( Wlc_NtkObjNumMax ( pNtk ) ) ;
int nOrigObjNum = Wlc_NtkObjNumMax ( pNtk ) ;
2017-02-26 07:26:51 +01:00
Wlc_Ntk_t * p = Wlc_NtkDupDfsSimple ( pNtk ) ;
2017-02-26 03:32:43 +01:00
Wlc_NtkForEachCi ( pNtk , pObj , i )
{
if ( ! Wlc_ObjIsPi ( pObj ) )
Vec_IntPush ( vFlops , Wlc_ObjId ( pNtk , pObj ) ) ;
}
Wlc_NtkForEachObjVec ( vNodes , pNtk , pObj , i )
Vec_IntWriteEntry ( vNodes , i , Wlc_ObjCopy ( pNtk , Wlc_ObjId ( pNtk , pObj ) ) ) ;
// mark nodes
Wlc_NtkForEachObjVec ( vNodes , p , pObj , i )
{
iObj = Wlc_ObjId ( p , pObj ) ;
pObj - > Mark = 1 ;
// add fresh PI with the same number of bits
Vec_IntWriteEntry ( vMapNode2Pi , iObj , Wlc_ObjAlloc ( p , WLC_OBJ_PI , Wlc_ObjIsSigned ( pObj ) , Wlc_ObjRange ( pObj ) - 1 , 0 ) ) ;
}
Wlc_NtkCleanCopy ( p ) ;
Wlc_NtkForEachObj ( p , pObj , i )
{
if ( i = = nOrigObjNum )
break ;
if ( pObj - > Mark ) {
// clean
pObj - > Mark = 0 ;
iObj = Vec_IntEntry ( vMapNode2Pi , i ) ;
}
else {
// update fanins
Wlc_ObjForEachFanin ( pObj , iFanin , k )
Wlc_ObjFanins ( pObj ) [ k ] = Wlc_ObjCopy ( p , iFanin ) ;
// node to remain
iObj = i ;
}
Wlc_ObjSetCopy ( p , i , iObj ) ;
}
Wlc_NtkForEachCo ( p , pObj , i )
{
iObj = Wlc_ObjId ( p , pObj ) ;
if ( iObj ! = Wlc_ObjCopy ( p , iObj ) )
{
if ( pObj - > fIsFi )
Wlc_NtkObj ( p , Wlc_ObjCopy ( p , iObj ) ) - > fIsFi = 1 ;
else
Wlc_NtkObj ( p , Wlc_ObjCopy ( p , iObj ) ) - > fIsPo = 1 ;
Vec_IntWriteEntry ( & p - > vCos , i , Wlc_ObjCopy ( p , iObj ) ) ;
}
}
pNew = Wlc_NtkDupDfsSimple ( p ) ;
Vec_IntFree ( vMapNode2Pi ) ;
Vec_IntFree ( vNodes ) ;
Wlc_NtkFree ( p ) ;
if ( pvFlops )
* pvFlops = vFlops ;
else
Vec_IntFree ( vFlops ) ;
return pNew ;
}
2017-02-26 07:26:51 +01:00
static int Wlc_NtkProofRefine ( Wlc_Ntk_t * p , Wlc_Par_t * pPars , Abc_Cex_t * pCex , Vec_Int_t * vBlacks , Vec_Int_t * * pvRefine )
2017-02-26 03:32:43 +01:00
{
2017-03-01 05:15:33 +01:00
Gia_Man_t * pGiaFrames ;
2017-02-26 07:26:51 +01:00
Vec_Int_t * vRefine = NULL ;
Vec_Bit_t * vUnmark ;
Vec_Bit_t * vChoiceMark ;
Wlc_Ntk_t * pNtkWithChoices = NULL ;
2017-02-26 03:32:43 +01:00
Vec_Int_t * vCoreSels ;
int num_ppis = - 1 ;
int Entry , i ;
2017-02-26 07:26:51 +01:00
if ( * pvRefine = = NULL )
return 0 ;
vUnmark = Vec_BitStart ( Wlc_NtkObjNumMax ( p ) ) ;
vChoiceMark = Vec_BitStart ( Vec_IntSize ( vBlacks ) ) ;
Vec_IntForEachEntry ( * pvRefine , Entry , i )
Vec_BitWriteEntry ( vUnmark , Entry , 1 ) ;
Vec_IntForEachEntry ( vBlacks , Entry , i )
{
if ( Vec_BitEntry ( vUnmark , Entry ) )
Vec_BitWriteEntry ( vChoiceMark , i , 1 ) ;
}
2017-03-01 05:15:33 +01:00
pNtkWithChoices = vBlacks ? Wlc_NtkIntroduceChoices ( p , vBlacks ) : NULL ;
2017-03-10 06:43:18 +01:00
pGiaFrames = Wlc_NtkUnrollWithCex ( pNtkWithChoices , pCex , Wlc_NtkNumPiBits ( p ) , Vec_IntSize ( vBlacks ) , & num_ppis , 0 , pPars - > fProofUsePPI ) ;
if ( ! pPars - > fProofUsePPI )
vCoreSels = Wlc_NtkGetCoreSels ( pGiaFrames , pCex - > iFrame + 1 , Vec_IntSize ( vBlacks ) , num_ppis , vChoiceMark , 0 , 0 , pPars ) ;
else
vCoreSels = Wlc_NtkGetCoreSels ( pGiaFrames , pCex - > iFrame + 1 , Vec_IntSize ( vBlacks ) , 0 , vChoiceMark , 0 , 0 , pPars ) ;
2017-02-26 07:26:51 +01:00
Wlc_NtkFree ( pNtkWithChoices ) ;
Gia_ManStop ( pGiaFrames ) ;
Vec_BitFree ( vUnmark ) ;
Vec_BitFree ( vChoiceMark ) ;
assert ( Vec_IntSize ( vCoreSels ) ) ;
2017-02-26 03:32:43 +01:00
2017-02-26 07:26:51 +01:00
vRefine = Vec_IntAlloc ( 100 ) ;
2017-02-26 03:32:43 +01:00
Vec_IntForEachEntry ( vCoreSels , Entry , i )
Vec_IntPush ( vRefine , Vec_IntEntry ( vBlacks , Entry ) ) ;
Vec_IntFree ( vCoreSels ) ;
2017-02-26 23:38:38 +01:00
if ( pPars - > fVerbose )
Abc_Print ( 1 , " Proof-based refinement reduces %d (out of %d) white boxes \n " , Vec_IntSize ( * pvRefine ) - Vec_IntSize ( vRefine ) , Vec_IntSize ( * pvRefine ) ) ;
2017-02-26 07:26:51 +01:00
Vec_IntFree ( * pvRefine ) ;
* pvRefine = vRefine ;
2017-02-26 03:32:43 +01:00
2017-02-26 07:26:51 +01:00
return 0 ;
2017-02-26 03:32:43 +01:00
}
2017-02-26 23:38:38 +01:00
static int Wlc_NtkUpdateBlacks ( Wlc_Ntk_t * p , Wlc_Par_t * pPars , Vec_Int_t * * pvBlacks , Vec_Bit_t * vUnmark )
{
int Entry , i ;
Wlc_Obj_t * pObj ; int Count [ 4 ] = { 0 } ;
Vec_Int_t * vBlacks = Vec_IntAlloc ( 100 ) ;
2014-11-15 05:12:20 +01:00
2017-02-26 23:38:38 +01:00
assert ( * pvBlacks ) ;
2014-11-15 05:12:20 +01:00
2017-02-26 23:38:38 +01:00
Vec_IntForEachEntry ( * pvBlacks , Entry , i )
{
if ( Vec_BitEntry ( vUnmark , Entry ) )
continue ;
Vec_IntPush ( vBlacks , Entry ) ;
2014-11-15 05:12:20 +01:00
2017-02-26 23:38:38 +01:00
pObj = Wlc_NtkObj ( p , Entry ) ;
if ( pObj - > Type = = WLC_OBJ_ARI_ADD | | pObj - > Type = = WLC_OBJ_ARI_SUB | | pObj - > Type = = WLC_OBJ_ARI_MINUS )
Count [ 0 ] + + ;
else 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 )
Count [ 1 ] + + ;
else if ( pObj - > Type = = WLC_OBJ_MUX )
Count [ 2 ] + + ;
else if ( Wlc_ObjIsCi ( pObj ) & & ! Wlc_ObjIsPi ( pObj ) )
Count [ 3 ] + + ;
}
Vec_IntFree ( * pvBlacks ) ;
* pvBlacks = vBlacks ;
if ( pPars - > fVerbose )
2017-02-27 22:45:22 +01:00
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 ] , Vec_IntSize ( vBlacks ) - Count [ 0 ] - Count [ 1 ] - Count [ 2 ] ) ;
2017-02-26 23:38:38 +01:00
return 0 ;
}
2014-11-15 05:12:20 +01:00
2017-02-27 23:31:59 +01:00
static Vec_Bit_t * Wlc_NtkMarkLimit ( Wlc_Ntk_t * p , Wlc_Par_t * pPars )
2017-02-27 00:39:48 +01:00
{
2017-02-27 23:31:59 +01:00
Vec_Bit_t * vMarks = NULL ;
Vec_Ptr_t * vAdds = Vec_PtrAlloc ( 1000 ) ;
2017-02-27 00:39:48 +01:00
Vec_Ptr_t * vMuxes = Vec_PtrAlloc ( 1000 ) ;
2017-02-27 23:31:59 +01:00
Vec_Ptr_t * vMults = Vec_PtrAlloc ( 1000 ) ;
Vec_Ptr_t * vFlops = Vec_PtrAlloc ( 1000 ) ;
2017-02-27 00:39:48 +01:00
Wlc_Obj_t * pObj ; int i ;
Int_Pair_t * pPair ;
2017-02-27 23:31:59 +01:00
if ( pPars - > nLimit = = ABC_INFINITY )
2017-02-27 00:39:48 +01:00
return NULL ;
2017-02-27 23:31:59 +01:00
vMarks = Vec_BitStart ( Wlc_NtkObjNumMax ( p ) ) ;
2017-02-27 00:39:48 +01:00
Wlc_NtkForEachObj ( p , pObj , i )
{
2017-02-27 23:31:59 +01:00
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 )
{
pPair = ABC_ALLOC ( Int_Pair_t , 1 ) ;
pPair - > first = i ;
pPair - > second = Wlc_ObjRange ( pObj ) ;
Vec_PtrPush ( vAdds , pPair ) ;
}
}
else 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 )
{
pPair = ABC_ALLOC ( Int_Pair_t , 1 ) ;
pPair - > first = i ;
pPair - > second = Wlc_ObjRange ( pObj ) ;
Vec_PtrPush ( vMults , pPair ) ;
}
}
else if ( pObj - > Type = = WLC_OBJ_MUX )
{
2017-02-27 00:39:48 +01:00
if ( Wlc_ObjRange ( pObj ) > = pPars - > nBitsMux )
{
pPair = ABC_ALLOC ( Int_Pair_t , 1 ) ;
pPair - > first = i ;
pPair - > second = Wlc_ObjRange ( pObj ) ;
Vec_PtrPush ( vMuxes , pPair ) ;
}
}
2017-02-27 23:31:59 +01:00
else if ( Wlc_ObjIsCi ( pObj ) & & ! Wlc_ObjIsPi ( pObj ) )
{
if ( Wlc_ObjRange ( pObj ) > = pPars - > nBitsFlop )
{
pPair = ABC_ALLOC ( Int_Pair_t , 1 ) ;
pPair - > first = i ;
pPair - > second = Wlc_ObjRange ( pObj ) ;
Vec_PtrPush ( vFlops , pPair ) ;
}
}
2017-02-27 00:39:48 +01:00
}
2017-02-27 23:31:59 +01:00
Vec_PtrSort ( vAdds , ( int ( * ) ( void ) ) IntPairPtrCompare ) ;
Vec_PtrSort ( vMults , ( int ( * ) ( void ) ) IntPairPtrCompare ) ;
2017-02-27 00:39:48 +01:00
Vec_PtrSort ( vMuxes , ( int ( * ) ( void ) ) IntPairPtrCompare ) ;
2017-02-27 23:31:59 +01:00
Vec_PtrSort ( vFlops , ( int ( * ) ( void ) ) IntPairPtrCompare ) ;
2017-02-27 00:39:48 +01:00
2017-02-27 23:31:59 +01:00
Vec_PtrForEachEntry ( Int_Pair_t * , vAdds , pPair , i )
2017-02-27 00:39:48 +01:00
{
2017-02-27 23:31:59 +01:00
if ( i > = pPars - > nLimit ) break ;
Vec_BitWriteEntry ( vMarks , pPair - > first , 1 ) ;
2017-02-27 00:39:48 +01:00
}
2017-02-27 23:31:59 +01:00
if ( i & & pPars - > fVerbose ) Abc_Print ( 1 , " %%PDRA: %d-th ADD has width = %d \n " , i , pPair - > second ) ;
2017-02-27 00:39:48 +01:00
2017-02-27 23:31:59 +01:00
Vec_PtrForEachEntry ( Int_Pair_t * , vMults , pPair , i )
{
if ( i > = pPars - > nLimit ) break ;
Vec_BitWriteEntry ( vMarks , pPair - > first , 1 ) ;
}
if ( i & & pPars - > fVerbose ) Abc_Print ( 1 , " %%PDRA: %d-th MUL has width = %d \n " , i , pPair - > second ) ;
2017-02-27 00:39:48 +01:00
Vec_PtrForEachEntry ( Int_Pair_t * , vMuxes , pPair , i )
2017-02-27 23:31:59 +01:00
{
if ( i > = pPars - > nLimit ) break ;
Vec_BitWriteEntry ( vMarks , pPair - > first , 1 ) ;
}
if ( i & & pPars - > fVerbose ) Abc_Print ( 1 , " %%PDRA: %d-th MUX has width = %d \n " , i , pPair - > second ) ;
Vec_PtrForEachEntry ( Int_Pair_t * , vFlops , pPair , i )
{
if ( i > = pPars - > nLimit ) break ;
Vec_BitWriteEntry ( vMarks , pPair - > first , 1 ) ;
}
if ( i & & pPars - > fVerbose ) Abc_Print ( 1 , " %%PDRA: %d-th FF has width = %d \n " , i , pPair - > second ) ;
Vec_PtrForEachEntry ( Int_Pair_t * , vAdds , pPair , i ) ABC_FREE ( pPair ) ;
Vec_PtrForEachEntry ( Int_Pair_t * , vMults , pPair , i ) ABC_FREE ( pPair ) ;
Vec_PtrForEachEntry ( Int_Pair_t * , vMuxes , pPair , i ) ABC_FREE ( pPair ) ;
Vec_PtrForEachEntry ( Int_Pair_t * , vFlops , pPair , i ) ABC_FREE ( pPair ) ;
Vec_PtrFree ( vAdds ) ;
Vec_PtrFree ( vMults ) ;
2017-02-27 00:39:48 +01:00
Vec_PtrFree ( vMuxes ) ;
2017-02-27 23:31:59 +01:00
Vec_PtrFree ( vFlops ) ;
2017-02-27 00:39:48 +01:00
2017-02-27 23:31:59 +01:00
return vMarks ;
2017-02-27 00:39:48 +01:00
}
2017-02-28 05:44:19 +01:00
static void Wlc_NtkSetUnmark ( Wlc_Ntk_t * p , Wlc_Par_t * pPars , Vec_Bit_t * vUnmark )
{
int Entry , i ;
Vec_Bit_t * vMarks = Wlc_NtkMarkLimit ( p , pPars ) ;
Vec_BitForEachEntry ( vMarks , Entry , i )
Vec_BitWriteEntry ( vUnmark , i , Entry ^ 1 ) ;
Vec_BitFree ( vMarks ) ;
}
2017-02-27 23:31:59 +01:00
static Vec_Int_t * Wlc_NtkGetBlacks ( Wlc_Ntk_t * p , Wlc_Par_t * pPars )
2017-02-26 03:32:43 +01:00
{
Vec_Int_t * vBlacks = Vec_IntAlloc ( 100 ) ;
Wlc_Obj_t * pObj ; int i , Count [ 4 ] = { 0 } ;
2017-02-27 23:31:59 +01:00
Vec_Bit_t * vMarks = NULL ;
2017-03-10 02:33:00 +01:00
int nTotal = 0 ;
2017-02-27 00:39:48 +01:00
2017-02-27 23:31:59 +01:00
vMarks = Wlc_NtkMarkLimit ( p , pPars ) ;
2017-02-27 00:39:48 +01:00
2017-02-26 03:32:43 +01:00
Wlc_NtkForEachObj ( p , pObj , i )
{
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 )
2017-02-27 23:31:59 +01:00
{
2017-03-10 02:33:00 +01:00
+ + nTotal ;
2017-02-27 23:31:59 +01:00
if ( vMarks = = NULL )
Vec_IntPushUniqueOrder ( vBlacks , Wlc_ObjId ( p , pObj ) ) , Count [ 0 ] + + ;
else if ( Vec_BitEntry ( vMarks , i ) )
Vec_IntPushUniqueOrder ( vBlacks , Wlc_ObjId ( p , pObj ) ) , Count [ 0 ] + + ;
}
2017-02-26 03:32:43 +01:00
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 )
2017-02-27 23:31:59 +01:00
{
2017-03-10 02:33:00 +01:00
+ + nTotal ;
2017-02-27 23:31:59 +01:00
if ( vMarks = = NULL )
Vec_IntPushUniqueOrder ( vBlacks , Wlc_ObjId ( p , pObj ) ) , Count [ 1 ] + + ;
else if ( Vec_BitEntry ( vMarks , i ) )
Vec_IntPushUniqueOrder ( vBlacks , Wlc_ObjId ( p , pObj ) ) , Count [ 1 ] + + ;
}
2017-02-26 03:32:43 +01:00
continue ;
}
if ( pObj - > Type = = WLC_OBJ_MUX )
{
if ( Wlc_ObjRange ( pObj ) > = pPars - > nBitsMux )
2017-02-27 00:39:48 +01:00
{
2017-03-10 02:33:00 +01:00
+ + nTotal ;
2017-02-27 23:31:59 +01:00
if ( vMarks = = NULL )
2017-02-27 22:45:22 +01:00
Vec_IntPushUniqueOrder ( vBlacks , Wlc_ObjId ( p , pObj ) ) , Count [ 2 ] + + ;
2017-02-27 23:31:59 +01:00
else if ( Vec_BitEntry ( vMarks , i ) )
2017-02-27 22:45:22 +01:00
Vec_IntPushUniqueOrder ( vBlacks , Wlc_ObjId ( p , pObj ) ) , Count [ 2 ] + + ;
2017-02-27 00:39:48 +01:00
}
2017-02-26 03:32:43 +01:00
continue ;
}
if ( Wlc_ObjIsCi ( pObj ) & & ! Wlc_ObjIsPi ( pObj ) )
{
if ( Wlc_ObjRange ( pObj ) > = pPars - > nBitsFlop )
2017-02-27 23:31:59 +01:00
{
2017-03-10 02:33:00 +01:00
+ + nTotal ;
2017-02-27 23:31:59 +01:00
if ( vMarks = = NULL )
Vec_IntPushUniqueOrder ( vBlacks , Wlc_ObjId ( p , Wlc_ObjFo2Fi ( p , pObj ) ) ) , Count [ 3 ] + + ;
else if ( Vec_BitEntry ( vMarks , i ) )
Vec_IntPushUniqueOrder ( vBlacks , Wlc_ObjId ( p , Wlc_ObjFo2Fi ( p , pObj ) ) ) , Count [ 3 ] + + ;
}
2017-02-26 03:32:43 +01:00
continue ;
}
}
2017-02-27 23:31:59 +01:00
if ( vMarks )
Vec_BitFree ( vMarks ) ;
2017-02-26 03:32:43 +01:00
if ( pPars - > fVerbose )
2017-03-10 02:33:00 +01:00
printf ( " Abstraction engine marked %d adds/subs, %d muls/divs, %d muxes, and %d flops to be abstracted away (out of %d signals). \n " , Count [ 0 ] , Count [ 1 ] , Count [ 2 ] , Count [ 3 ] , nTotal ) ;
2017-02-26 03:32:43 +01:00
return vBlacks ;
}
2017-02-26 23:38:38 +01:00
/**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 [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-02-22 05:06:13 +01:00
static Vec_Bit_t * Wlc_NtkAbsMarkOpers ( Wlc_Ntk_t * p , Wlc_Par_t * pPars , Vec_Bit_t * vUnmark , int fVerbose )
2014-11-15 05:12:20 +01:00
{
2017-02-16 02:16:19 +01:00
Vec_Bit_t * vLeaves = Vec_BitStart ( Wlc_NtkObjNumMax ( p ) ) ;
Wlc_Obj_t * pObj ; int i , Count [ 4 ] = { 0 } ;
Wlc_NtkForEachObj ( p , pObj , i )
2014-11-15 05:12:20 +01:00
{
2017-02-16 02:16:19 +01:00
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 ;
}
2014-11-15 05:12:20 +01:00
}
2017-02-16 02:16:19 +01:00
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 ;
2014-11-15 05:12:20 +01:00
}
/**Function*************************************************************
2017-02-16 02:16:19 +01:00
Synopsis [ Marks nodes to be included in the abstracted network . ]
2014-11-15 05:12:20 +01:00
2017-02-16 02:16:19 +01:00
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 . ]
2014-11-15 05:12:20 +01:00
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-02-16 02:16:19 +01:00
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 )
2014-11-15 05:12:20 +01:00
{
2017-02-16 02:16:19 +01:00
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 ) ;
2017-02-19 21:31:28 +01:00
2017-02-22 07:20:03 +01:00
/*
2017-02-19 21:31:28 +01:00
Vec_IntClear ( vFlops ) ;
Wlc_NtkForEachCi ( p , pObj , i ) {
if ( ! Wlc_ObjIsPi ( pObj ) ) {
Vec_IntPush ( vFlops , Wlc_ObjId ( p , pObj ) ) ;
pObj - > Mark = 1 ;
}
}
2017-02-22 07:20:03 +01:00
*/
2017-02-19 21:31:28 +01:00
2017-02-16 02:16:19 +01:00
Wlc_NtkForEachObjVec ( vFlops , p , pObj , i )
Wlc_NtkAbsMarkNodes_rec ( p , Wlc_ObjFo2Fi ( p , pObj ) , vLeaves , vPisOld , vPisNew , vFlops ) ;
2014-11-15 05:12:20 +01:00
Wlc_NtkForEachObj ( p , pObj , i )
2017-02-16 02:16:19 +01:00
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 ) ;
2014-11-15 05:12:20 +01:00
}
/**Function*************************************************************
2017-02-16 02:16:19 +01:00
Synopsis [ Derive word - level abstracted model based on the parameter values . ]
2014-11-15 05:12:20 +01:00
2017-02-16 02:16:19 +01:00
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 . ]
2014-11-15 05:12:20 +01:00
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-02-22 07:20:03 +01:00
static Wlc_Ntk_t * Wlc_NtkAbs ( Wlc_Ntk_t * p , Wlc_Par_t * pPars , Vec_Bit_t * vUnmark , Vec_Int_t * * pvPisNew , Vec_Int_t * * pvFlops , int fVerbose )
2014-11-15 05:12:20 +01:00
{
2017-02-16 02:16:19 +01:00
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 ) ;
2017-02-22 07:20:03 +01:00
if ( pvFlops )
* pvFlops = vFlops ;
else
Vec_IntFree ( vFlops ) ;
2017-02-16 02:16:19 +01:00
if ( pvPisNew )
* pvPisNew = vPisNew ;
else
Vec_IntFree ( vPisNew ) ;
return pNtkNew ;
2014-11-15 05:12:20 +01:00
}
2017-02-16 02:16:19 +01:00
/**Function*************************************************************
Synopsis [ Find what objects need to be un - abstracted . ]
2014-11-15 05:12:20 +01:00
2017-02-16 02:16:19 +01:00
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 ;
}
2014-11-15 05:12:20 +01:00
/**Function*************************************************************
2017-02-16 02:16:19 +01:00
Synopsis [ Mark MFFC cones of the un - abstracted objects . ]
2014-11-15 05:12:20 +01:00
2017-02-16 02:16:19 +01:00
Description [ The MFFC cones of the objects in vRefine are traversed
and all their nodes are marked in vUnmark . ]
2014-11-15 05:12:20 +01:00
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-02-16 02:16:19 +01:00
static int Wlc_NtkNodeDeref_rec ( Wlc_Ntk_t * p , Wlc_Obj_t * pNode , Vec_Bit_t * vUnmark )
2014-11-15 05:12:20 +01:00
{
2017-02-16 02:16:19 +01:00
int i , Fanin , Counter = 1 ;
if ( Wlc_ObjIsCi ( pNode ) )
return 0 ;
Vec_BitWriteEntry ( vUnmark , Wlc_ObjId ( p , pNode ) , 1 ) ;
Wlc_ObjForEachFanin ( pNode , Fanin , i )
2014-11-15 05:12:20 +01:00
{
2017-02-16 02:16:19 +01:00
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 ) ;
2014-11-15 05:12:20 +01:00
}
2017-02-16 02:16:19 +01:00
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 ;
2014-11-15 05:12:20 +01:00
}
2017-02-23 02:57:19 +01:00
static int Wlc_NtkUnmarkRefinement ( Wlc_Ntk_t * p , Vec_Int_t * vRefine , Vec_Bit_t * vUnmark )
{
Wlc_Obj_t * pObj ; int i , nNodes = 0 ;
Wlc_NtkForEachObjVec ( vRefine , p , pObj , i )
{
Vec_BitWriteEntry ( vUnmark , Wlc_ObjId ( p , pObj ) , 1 ) ;
+ + nNodes ;
}
return nNodes ;
}
2017-02-22 07:20:03 +01:00
/**Function*************************************************************
Synopsis [ Computes the map for remapping flop IDs used in the clauses . ]
Description [ Takes the original network ( Wlc_Ntk_t ) and the array of word - level
flops used in the old abstraction ( vFfOld ) and those used in the new abstraction
( vFfNew ) . Returns the integer map , which remaps every binary flop found
in the old abstraction into a binary flop found in the new abstraction . ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Vec_Int_t * Wlc_NtkFlopsRemap ( Wlc_Ntk_t * p , Vec_Int_t * vFfOld , Vec_Int_t * vFfNew )
{
Vec_Int_t * vMap = Vec_IntAlloc ( 1000 ) ; // the resulting map
Vec_Int_t * vMapFfNew2Bit1 = Vec_IntAlloc ( 1000 ) ; // first binary bit of each new word-level flop
int i , b , iFfOld , iFfNew , iBit1New , nBits = 0 ;
// map object IDs of old flops into their flop indexes
Vec_Int_t * vMapFfObj2FfId = Vec_IntStartFull ( Wlc_NtkObjNumMax ( p ) ) ;
Vec_IntForEachEntry ( vFfNew , iFfNew , i )
Vec_IntWriteEntry ( vMapFfObj2FfId , iFfNew , i ) ;
// map each new flop index into its first bit
Vec_IntForEachEntry ( vFfNew , iFfNew , i )
{
Wlc_Obj_t * pObj = Wlc_NtkObj ( p , iFfNew ) ;
int nRange = Wlc_ObjRange ( pObj ) ;
Vec_IntPush ( vMapFfNew2Bit1 , nBits ) ;
nBits + = nRange ;
}
assert ( Vec_IntSize ( vMapFfNew2Bit1 ) = = Vec_IntSize ( vFfNew ) ) ;
// remap old binary flops into new binary flops
Vec_IntForEachEntry ( vFfOld , iFfOld , i )
{
Wlc_Obj_t * pObj = Wlc_NtkObj ( p , iFfOld ) ;
int nRange = Wlc_ObjRange ( pObj ) ;
iFfNew = Vec_IntEntry ( vMapFfObj2FfId , iFfOld ) ;
assert ( iFfNew > = 0 ) ; // every old flop should be present in the new abstraction
// find the first bit of this new flop
iBit1New = Vec_IntEntry ( vMapFfNew2Bit1 , iFfNew ) ;
for ( b = 0 ; b < nRange ; b + + )
Vec_IntPush ( vMap , iBit1New + b ) ;
}
Vec_IntFree ( vMapFfNew2Bit1 ) ;
Vec_IntFree ( vMapFfObj2FfId ) ;
return vMap ;
}
2017-02-19 18:55:58 +01:00
/**Function*************************************************************
Synopsis [ Performs PDR with word - level abstraction . ]
Description [ ]
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-02-22 05:06:13 +01:00
int Wlc_NtkPdrAbs ( Wlc_Ntk_t * p , Wlc_Par_t * pPars )
2017-02-19 18:55:58 +01:00
{
abctime clk = Abc_Clock ( ) ;
2017-02-28 20:30:13 +01:00
abctime clk2 ;
abctime tPdr = 0 , tCbr = 0 , tPbr = 0 , tTotal = 0 ;
2017-02-19 19:22:15 +01:00
Pdr_Man_t * pPdr ;
Vec_Vec_t * vClauses = NULL ;
2017-02-22 07:20:03 +01:00
Vec_Int_t * vFfOld = NULL , * vFfNew = NULL , * vMap = NULL ;
2017-02-26 23:38:38 +01:00
Vec_Int_t * vBlacks = NULL ;
2017-02-22 07:20:03 +01:00
int nIters , nNodes , nDcFlops , RetValue = - 1 , nGiaFfNumOld = - 1 ;
2017-03-09 20:07:58 +01:00
int nTotalCla = 0 ;
2017-02-19 18:55:58 +01:00
// 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 ;
2017-02-20 00:57:13 +01:00
pPdrPars - > fVeryVerbose = 0 ;
2017-02-19 18:55:58 +01:00
2017-02-23 17:48:53 +01:00
if ( pPars - > fPdra )
{
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
}
2017-02-19 18:55:58 +01:00
// perform refinement iterations
for ( nIters = 1 ; nIters < pPars - > nIterMax ; nIters + + )
{
Aig_Man_t * pAig ;
Abc_Cex_t * pCex ;
2017-02-26 03:32:43 +01:00
Vec_Int_t * vPisNew = NULL ;
Vec_Int_t * vRefine ;
2017-02-19 18:55:58 +01:00
Gia_Man_t * pGia , * pTemp ;
Wlc_Ntk_t * pAbs ;
if ( pPars - > fVerbose )
printf ( " \n Iteration %d: \n " , nIters ) ;
// get abstracted GIA and the set of pseudo-PIs (vPisNew)
2017-03-09 22:07:30 +01:00
if ( pPars - > fAbs2 | | pPars - > fProofRefine )
2017-02-26 03:32:43 +01:00
{
2017-02-26 23:38:38 +01:00
if ( vBlacks = = NULL )
2017-02-27 23:31:59 +01:00
vBlacks = Wlc_NtkGetBlacks ( p , pPars ) ;
2017-02-26 23:38:38 +01:00
else
Wlc_NtkUpdateBlacks ( p , pPars , & vBlacks , vUnmark ) ;
pAbs = Wlc_NtkAbs2 ( p , vBlacks , & vFfNew ) ;
vPisNew = Vec_IntDup ( vBlacks ) ;
2017-02-26 03:32:43 +01:00
}
else
{
2017-02-28 05:44:19 +01:00
if ( nIters = = 1 & & pPars - > nLimit < ABC_INFINITY )
Wlc_NtkSetUnmark ( p , pPars , vUnmark ) ;
2017-02-26 03:32:43 +01:00
pAbs = Wlc_NtkAbs ( p , pPars , vUnmark , & vPisNew , & vFfNew , pPars - > fVerbose ) ;
}
2017-02-19 18:55:58 +01:00
pGia = Wlc_NtkBitBlast ( pAbs , NULL , - 1 , 0 , 0 , 0 , 0 ) ;
2017-02-22 07:20:03 +01:00
// map old flops into new flops
if ( vFfOld )
{
assert ( nGiaFfNumOld > = 0 ) ;
vMap = Wlc_NtkFlopsRemap ( p , vFfOld , vFfNew ) ;
//Vec_IntPrint( vMap );
// if reset flop was added in the previous iteration, it will be added again in this iteration
// remap the last flop (reset flop) into the last flop (reset flop) of the current AIG
if ( Vec_IntSize ( vMap ) + 1 = = nGiaFfNumOld )
Vec_IntPush ( vMap , Gia_ManRegNum ( pGia ) - 1 ) ;
assert ( Vec_IntSize ( vMap ) = = nGiaFfNumOld ) ;
Vec_IntFreeP ( & vFfOld ) ;
}
ABC_SWAP ( Vec_Int_t * , vFfOld , vFfNew ) ;
nGiaFfNumOld = Gia_ManRegNum ( pGia ) ;
2017-02-19 18:55:58 +01:00
// 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 ) ;
2017-03-01 23:57:43 +01:00
// Gia_AigerWrite( pGia, "abs.aig", 0, 0 );
2017-02-19 18:55:58 +01:00
// try to prove abstracted GIA by converting it to AIG and calling PDR
pAig = Gia_ManToAigSimple ( pGia ) ;
2017-02-19 19:22:15 +01:00
2017-02-20 00:57:13 +01:00
2017-03-01 23:57:43 +01:00
if ( vClauses & & pPars - > fCheckCombUnsat )
{
2017-03-03 07:16:16 +01:00
Pdr_Man_t * pPdr2 ;
2017-03-03 21:29:15 +01:00
if ( Aig_ManAndNum ( pAig ) < = 20000 )
{
Aig_Man_t * pAigScorr ;
Ssw_Pars_t ScorrPars , * pScorrPars = & ScorrPars ;
int nAnds ;
clk2 = Abc_Clock ( ) ;
Ssw_ManSetDefaultParams ( pScorrPars ) ;
pScorrPars - > fStopWhenGone = 1 ;
pScorrPars - > nFramesK = 1 ;
pAigScorr = Ssw_SignalCorrespondence ( pAig , pScorrPars ) ;
assert ( pAigScorr ) ;
nAnds = Aig_ManAndNum ( pAigScorr ) ;
Aig_ManStop ( pAigScorr ) ;
if ( nAnds = = 0 )
{
if ( pPars - > fVerbose )
Abc_PrintTime ( 1 , " SCORR proved UNSAT. Time " , Abc_Clock ( ) - clk2 ) ;
RetValue = 1 ;
Gia_ManStop ( pGia ) ;
Vec_IntFree ( vPisNew ) ;
Aig_ManStop ( pAig ) ;
break ;
}
else if ( pPars - > fVerbose )
{
Abc_Print ( 1 , " SCORR failed with %d ANDs. " , nAnds ) ;
Abc_PrintTime ( 1 , " Time " , Abc_Clock ( ) - clk2 ) ;
}
2017-03-03 07:16:16 +01:00
}
2017-03-01 23:57:43 +01:00
clk2 = Abc_Clock ( ) ;
pPdrPars - > fVerbose = 0 ;
pPdr2 = Pdr_ManStart ( pAig , pPdrPars , NULL ) ;
RetValue = IPdr_ManCheckCombUnsat ( pPdr2 ) ;
Pdr_ManStop ( pPdr2 ) ;
pPdrPars - > fVerbose = pPars - > fPdrVerbose ;
tPdr + = Abc_Clock ( ) - clk2 ;
if ( RetValue = = 1 )
{
if ( pPars - > fVerbose )
Abc_PrintTime ( 1 , " ABS becomes combinationally UNSAT. Time " , Abc_Clock ( ) - clk2 ) ;
Gia_ManStop ( pGia ) ;
Vec_IntFree ( vPisNew ) ;
Aig_ManStop ( pAig ) ;
break ;
}
if ( pPars - > fVerbose )
Abc_PrintTime ( 1 , " Check comb. unsat failed. Time " , Abc_Clock ( ) - clk2 ) ;
}
clk2 = Abc_Clock ( ) ;
pPdr = Pdr_ManStart ( pAig , pPdrPars , NULL ) ;
2017-02-19 21:31:28 +01:00
if ( vClauses ) {
2017-02-20 00:57:13 +01:00
assert ( Vec_VecSize ( vClauses ) > = 2 ) ;
2017-02-22 07:20:03 +01:00
IPdr_ManRestore ( pPdr , vClauses , vMap ) ;
2017-02-19 21:31:28 +01:00
}
2017-02-22 07:20:03 +01:00
Vec_IntFreeP ( & vMap ) ;
2017-02-19 19:22:15 +01:00
2017-03-01 23:57:43 +01:00
if ( ! vClauses | | RetValue ! = 1 )
RetValue = IPdr_ManSolveInt ( pPdr , pPars - > fCheckClauses , pPars - > fPushClauses ) ;
2017-02-28 20:30:13 +01:00
pPdr - > tTotal + = Abc_Clock ( ) - clk2 ;
tPdr + = pPdr - > tTotal ;
2017-02-19 19:22:15 +01:00
2017-02-19 18:55:58 +01:00
pCex = pAig - > pSeqModel ; pAig - > pSeqModel = NULL ;
// consider outcomes
if ( pCex = = NULL )
{
assert ( RetValue ) ; // proved or undecided
Gia_ManStop ( pGia ) ;
Vec_IntFree ( vPisNew ) ;
2017-02-19 19:22:15 +01:00
Pdr_ManStop ( pPdr ) ;
Aig_ManStop ( pAig ) ;
2017-02-19 18:55:58 +01:00
break ;
}
2017-03-01 21:12:42 +01:00
// verify CEX
if ( Wlc_NtkCexIsReal ( p , pCex ) )
{
vRefine = NULL ;
Abc_CexFree ( pCex ) ; // return CEX in the future
Pdr_ManStop ( pPdr ) ;
Aig_ManStop ( pAig ) ;
break ;
}
2017-02-19 18:55:58 +01:00
// perform refinement
2017-03-01 03:05:58 +01:00
if ( pPars - > fHybrid | | ! pPars - > fProofRefine )
{
clk2 = Abc_Clock ( ) ;
vRefine = Wlc_NtkAbsRefinement ( p , pGia , pCex , vPisNew ) ;
tCbr + = Abc_Clock ( ) - clk2 ;
}
else // proof-based only
{
vRefine = Vec_IntDup ( vPisNew ) ;
}
2017-02-26 03:32:43 +01:00
if ( pPars - > fProofRefine )
2017-02-28 20:30:13 +01:00
{
clk2 = Abc_Clock ( ) ;
2017-02-26 07:26:51 +01:00
Wlc_NtkProofRefine ( p , pPars , pCex , vPisNew , & vRefine ) ;
2017-02-28 20:30:13 +01:00
tPbr + = Abc_Clock ( ) - clk2 ;
}
2017-02-19 18:55:58 +01:00
Gia_ManStop ( pGia ) ;
Vec_IntFree ( vPisNew ) ;
if ( vRefine = = NULL ) // real CEX
{
Abc_CexFree ( pCex ) ; // return CEX in the future
2017-02-19 19:22:15 +01:00
Pdr_ManStop ( pPdr ) ;
Aig_ManStop ( pAig ) ;
2017-02-19 18:55:58 +01:00
break ;
}
2017-02-19 19:22:15 +01:00
// spurious CEX, continue solving
2017-02-20 01:09:59 +01:00
vClauses = IPdr_ManSaveClauses ( pPdr , 0 ) ;
2017-03-09 20:07:58 +01:00
if ( vClauses & & pPars - > fVerbose )
{
int i ;
Vec_Ptr_t * vVec ;
Vec_VecForEachLevel ( vClauses , vVec , i )
nTotalCla + = Vec_PtrSize ( vVec ) ;
}
2017-02-20 19:13:18 +01:00
2017-02-19 19:22:15 +01:00
Pdr_ManStop ( pPdr ) ;
2017-02-19 18:55:58 +01:00
// update the set of objects to be un-abstracted
2017-02-28 20:30:13 +01:00
clk2 = Abc_Clock ( ) ;
2017-02-23 02:57:19 +01:00
if ( pPars - > fMFFC )
{
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 ) ;
}
else
{
nNodes = Wlc_NtkUnmarkRefinement ( p , vRefine , vUnmark ) ;
if ( pPars - > fVerbose )
printf ( " Refinement of CEX in frame %d came up with %d un-abstacted PPIs. \n " , pCex - > iFrame , Vec_IntSize ( vRefine ) ) ;
}
2017-02-28 20:30:13 +01:00
tCbr + = Abc_Clock ( ) - clk2 ;
2017-02-19 18:55:58 +01:00
Vec_IntFree ( vRefine ) ;
Abc_CexFree ( pCex ) ;
2017-02-19 19:22:15 +01:00
Aig_ManStop ( pAig ) ;
2017-02-19 18:55:58 +01:00
}
2017-02-26 03:32:43 +01:00
2017-02-26 23:38:38 +01:00
if ( vBlacks )
Vec_IntFree ( vBlacks ) ;
2017-02-22 07:20:03 +01:00
Vec_IntFreeP ( & vFfOld ) ;
2017-02-19 18:55:58 +01:00
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 ) ;
2017-02-28 20:30:13 +01:00
tTotal = Abc_Clock ( ) - clk ;
Abc_PrintTime ( 1 , " Time " , tTotal ) ;
2017-03-09 20:07:58 +01:00
if ( pPars - > fVerbose )
Abc_Print ( 1 , " PDRA reused %d clauses. \n " , nTotalCla ) ;
2017-02-28 20:30:13 +01:00
if ( pPars - > fVerbose )
{
ABC_PRTP ( " PDR " , tPdr , tTotal ) ;
ABC_PRTP ( " CEX Refine " , tCbr , tTotal ) ;
ABC_PRTP ( " Proof Refine " , tPbr , tTotal ) ;
ABC_PRTP ( " Misc. " , tTotal - tPdr - tCbr - tPbr , tTotal ) ;
ABC_PRTP ( " Total " , tTotal , tTotal ) ;
}
2017-02-19 18:55:58 +01:00
return RetValue ;
}
2014-11-15 05:12:20 +01:00
/**Function*************************************************************
2017-02-16 02:16:19 +01:00
Synopsis [ Performs abstraction . ]
2014-11-15 05:12:20 +01:00
2017-02-16 02:16:19 +01:00
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 . ]
2014-11-15 05:12:20 +01:00
SideEffects [ ]
SeeAlso [ ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-02-16 02:16:19 +01:00
int Wlc_NtkAbsCore ( Wlc_Ntk_t * p , Wlc_Par_t * pPars )
2014-11-15 05:12:20 +01:00
{
2017-02-16 02:16:19 +01:00
abctime clk = Abc_Clock ( ) ;
2017-03-09 22:20:56 +01:00
Vec_Int_t * vBlacks = NULL ;
2017-02-16 02:16:19 +01:00
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 ) ;
2017-02-19 21:31:28 +01:00
//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)
2017-02-16 02:16:19 +01:00
//pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
pPdrPars - > fVerbose = pPars - > fPdrVerbose ;
2017-02-20 00:57:13 +01:00
pPdrPars - > fVeryVerbose = 0 ;
2017-02-16 02:16:19 +01:00
// perform refinement iterations
for ( nIters = 1 ; nIters < pPars - > nIterMax ; nIters + + )
2014-11-15 05:12:20 +01:00
{
2017-02-16 02:16:19 +01:00
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 ( " \n Iteration %d: \n " , nIters ) ;
// get abstracted GIA and the set of pseudo-PIs (vPisNew)
2017-03-09 22:07:30 +01:00
if ( pPars - > fAbs2 )
{
if ( vBlacks = = NULL )
vBlacks = Wlc_NtkGetBlacks ( p , pPars ) ;
else
Wlc_NtkUpdateBlacks ( p , pPars , & vBlacks , vUnmark ) ;
pAbs = Wlc_NtkAbs2 ( p , vBlacks , NULL ) ;
vPisNew = Vec_IntDup ( vBlacks ) ;
}
else
{
if ( nIters = = 1 & & pPars - > nLimit < ABC_INFINITY )
Wlc_NtkSetUnmark ( p , pPars , vUnmark ) ;
pAbs = Wlc_NtkAbs ( p , pPars , vUnmark , & vPisNew , NULL , pPars - > fVerbose ) ;
}
2017-02-16 02:16:19 +01:00
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
2014-11-15 05:12:20 +01:00
{
2017-02-16 02:16:19 +01:00
pGia = Gia_ManPermuteInputs ( pTemp = pGia , Wlc_NtkCountObjBits ( p , vPisNew ) , nDcFlops ) ;
Gia_ManStop ( pTemp ) ;
2014-11-15 05:12:20 +01:00
}
2017-02-16 02:16:19 +01:00
// 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 ) ;
2014-11-15 05:12:20 +01:00
}
2017-03-09 22:20:56 +01:00
Vec_IntFree ( vBlacks ) ;
2017-02-16 02:16:19 +01:00
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 ;
2014-11-15 05:12:20 +01:00
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END