ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
wlcAbs2.c
Go to the documentation of this file.
1
20
21#include "wlc.h"
22#include "proof/pdr/pdr.h"
23#include "aig/gia/giaAig.h"
24#include "sat/bmc/bmc.h"
25
27
31
35
49static Vec_Bit_t * Wlc_NtkAbsMarkOpers( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, int fVerbose )
50{
51 Vec_Bit_t * vLeaves = Vec_BitStart( Wlc_NtkObjNumMax(p) );
52 Wlc_Obj_t * pObj; int i, Count[4] = {0};
53 Wlc_NtkForEachObj( p, pObj, i )
54 {
55 if ( vUnmark && Vec_BitEntry(vUnmark, i) ) // not allow this object to be abstracted away
56 continue;
57 if ( pObj->Type == WLC_OBJ_ARI_ADD || pObj->Type == WLC_OBJ_ARI_SUB || pObj->Type == WLC_OBJ_ARI_MINUS )
58 {
59 if ( Wlc_ObjRange(pObj) >= pPars->nBitsAdd )
60 Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[0]++;
61 continue;
62 }
63 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 )
64 {
65 if ( Wlc_ObjRange(pObj) >= pPars->nBitsMul )
66 Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[1]++;
67 continue;
68 }
69 if ( pObj->Type == WLC_OBJ_MUX )
70 {
71 if ( Wlc_ObjRange(pObj) >= pPars->nBitsMux )
72 Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[2]++;
73 continue;
74 }
75 if ( Wlc_ObjIsCi(pObj) && !Wlc_ObjIsPi(pObj) )
76 {
77 if ( Wlc_ObjRange(pObj) >= pPars->nBitsFlop )
78 Vec_BitWriteEntry( vLeaves, Wlc_ObjId(p, pObj), 1 ), Count[3]++;
79 continue;
80 }
81 }
82 if ( fVerbose )
83 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] );
84 return vLeaves;
85}
86
101static 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 )
102{
103 int i, iFanin;
104 if ( pObj->Mark )
105 return;
106 pObj->Mark = 1;
107 if ( Vec_BitEntry(vLeaves, Wlc_ObjId(p, pObj)) )
108 {
109 assert( !Wlc_ObjIsPi(pObj) );
110 Vec_IntPush( vPisNew, Wlc_ObjId(p, pObj) );
111 return;
112 }
113 if ( Wlc_ObjIsCi(pObj) )
114 {
115 if ( Wlc_ObjIsPi(pObj) )
116 Vec_IntPush( vPisOld, Wlc_ObjId(p, pObj) );
117 else
118 Vec_IntPush( vFlops, Wlc_ObjId(p, pObj) );
119 return;
120 }
121 Wlc_ObjForEachFanin( pObj, iFanin, i )
122 Wlc_NtkAbsMarkNodes_rec( p, Wlc_NtkObj(p, iFanin), vLeaves, vPisOld, vPisNew, vFlops );
123}
124static void Wlc_NtkAbsMarkNodes( Wlc_Ntk_t * p, Vec_Bit_t * vLeaves, Vec_Int_t * vPisOld, Vec_Int_t * vPisNew, Vec_Int_t * vFlops )
125{
126 Wlc_Obj_t * pObj;
127 int i, Count = 0;
129 Wlc_NtkForEachCo( p, pObj, i )
130 Wlc_NtkAbsMarkNodes_rec( p, pObj, vLeaves, vPisOld, vPisNew, vFlops );
131 Wlc_NtkForEachObjVec( vFlops, p, pObj, i )
132 Wlc_NtkAbsMarkNodes_rec( p, Wlc_ObjFo2Fi(p, pObj), vLeaves, vPisOld, vPisNew, vFlops );
133 Wlc_NtkForEachObj( p, pObj, i )
134 Count += pObj->Mark;
135// printf( "Collected %d old PIs, %d new PIs, %d flops, and %d other objects.\n",
136// Vec_IntSize(vPisOld), Vec_IntSize(vPisNew), Vec_IntSize(vFlops),
137// Count - Vec_IntSize(vPisOld) - Vec_IntSize(vPisNew) - Vec_IntSize(vFlops) );
138 Vec_IntSort( vPisOld, 0 );
139 Vec_IntSort( vPisNew, 0 );
140 Vec_IntSort( vFlops, 0 );
142}
143
159static Wlc_Ntk_t * Wlc_NtkAbs( Wlc_Ntk_t * p, Wlc_Par_t * pPars, Vec_Bit_t * vUnmark, Vec_Int_t ** pvPisNew, int fVerbose )
160{
161 Wlc_Ntk_t * pNtkNew = NULL;
162 Vec_Int_t * vPisOld = Vec_IntAlloc( 100 );
163 Vec_Int_t * vPisNew = Vec_IntAlloc( 100 );
164 Vec_Int_t * vFlops = Vec_IntAlloc( 100 );
165 Vec_Bit_t * vLeaves = Wlc_NtkAbsMarkOpers( p, pPars, vUnmark, fVerbose );
166 Wlc_NtkAbsMarkNodes( p, vLeaves, vPisOld, vPisNew, vFlops );
167 Vec_BitFree( vLeaves );
168 pNtkNew = Wlc_NtkDupDfsAbs( p, vPisOld, vPisNew, vFlops );
169 Vec_IntFree( vPisOld );
170 Vec_IntFree( vFlops );
171 if ( pvPisNew )
172 *pvPisNew = vPisNew;
173 else
174 Vec_IntFree( vPisNew );
175 return pNtkNew;
176}
177
192static Vec_Int_t * Wlc_NtkAbsRefinement( Wlc_Ntk_t * p, Gia_Man_t * pGia, Abc_Cex_t * pCex, Vec_Int_t * vPisNew )
193{
194 Vec_Int_t * vRefine = Vec_IntAlloc( 100 );
195 Abc_Cex_t * pCexCare;
196 Wlc_Obj_t * pObj;
197 // count the number of bit-level PPIs and map them into word-level objects they were derived from
198 int f, i, b, nRealPis, nPpiBits = 0;
199 Vec_Int_t * vMap = Vec_IntStartFull( pCex->nPis );
200 Wlc_NtkForEachObjVec( vPisNew, p, pObj, i )
201 for ( b = 0; b < Wlc_ObjRange(pObj); b++ )
202 Vec_IntWriteEntry( vMap, nPpiBits++, Wlc_ObjId(p, pObj) );
203 // since PPIs are ordered last, the previous bits are real PIs
204 nRealPis = pCex->nPis - nPpiBits;
205 // find the care-set
206 pCexCare = Bmc_CexCareMinimizeAig( pGia, nRealPis, pCex, 1, 0, 0 );
207 assert( pCexCare->nPis == pCex->nPis );
208 // detect care PPIs
209 for ( f = 0; f <= pCexCare->iFrame; f++ )
210 for ( i = nRealPis; i < pCexCare->nPis; i++ )
211 if ( Abc_InfoHasBit(pCexCare->pData, pCexCare->nRegs + pCexCare->nPis * f + i) )
212 Vec_IntPushUniqueOrder( vRefine, Vec_IntEntry(vMap, i-nRealPis) );
213 Abc_CexFree( pCexCare );
214 Vec_IntFree( vMap );
215 if ( Vec_IntSize(vRefine) == 0 )// real CEX
216 Vec_IntFreeP( &vRefine );
217 return vRefine;
218}
219
232static int Wlc_NtkNodeDeref_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
233{
234 int i, Fanin, Counter = 1;
235 if ( Wlc_ObjIsCi(pNode) )
236 return 0;
237 Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
238 Wlc_ObjForEachFanin( pNode, Fanin, i )
239 {
240 Vec_IntAddToEntry( &p->vRefs, Fanin, -1 );
241 if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
242 Counter += Wlc_NtkNodeDeref_rec( p, Wlc_NtkObj(p, Fanin), vUnmark );
243 }
244 return Counter;
245}
246static int Wlc_NtkNodeRef_rec( Wlc_Ntk_t * p, Wlc_Obj_t * pNode )
247{
248 int i, Fanin, Counter = 1;
249 if ( Wlc_ObjIsCi(pNode) )
250 return 0;
251 Wlc_ObjForEachFanin( pNode, Fanin, i )
252 {
253 if ( Vec_IntEntry(&p->vRefs, Fanin) == 0 )
254 Counter += Wlc_NtkNodeRef_rec( p, Wlc_NtkObj(p, Fanin) );
255 Vec_IntAddToEntry( &p->vRefs, Fanin, 1 );
256 }
257 return Counter;
258}
259static int Wlc_NtkMarkMffc( Wlc_Ntk_t * p, Wlc_Obj_t * pNode, Vec_Bit_t * vUnmark )
260{
261 int Count1, Count2;
262 // if this is a flop output, compute MFFC of the corresponding flop input
263 while ( Wlc_ObjIsCi(pNode) )
264 {
265 Vec_BitWriteEntry( vUnmark, Wlc_ObjId(p, pNode), 1 );
266 pNode = Wlc_ObjFo2Fi(p, pNode);
267 }
268 assert( !Wlc_ObjIsCi(pNode) );
269 // dereference the node (and set the bits in vUnmark)
270 Count1 = Wlc_NtkNodeDeref_rec( p, pNode, vUnmark );
271 // reference it back
272 Count2 = Wlc_NtkNodeRef_rec( p, pNode );
273 assert( Count1 == Count2 );
274 return Count1;
275}
276static int Wlc_NtkRemoveFromAbstraction( Wlc_Ntk_t * p, Vec_Int_t * vRefine, Vec_Bit_t * vUnmark )
277{
278 Wlc_Obj_t * pObj; int i, nNodes = 0;
279 if ( Vec_IntSize(&p->vRefs) == 0 )
280 Wlc_NtkSetRefs( p );
281 Wlc_NtkForEachObjVec( vRefine, p, pObj, i )
282 nNodes += Wlc_NtkMarkMffc( p, pObj, vUnmark );
283 return nNodes;
284}
285
303{
304 abctime clk = Abc_Clock();
305 int nIters, nNodes, nDcFlops, RetValue = -1;
306 // start the bitmap to mark objects that cannot be abstracted because of refinement
307 // currently, this bitmap is empty because abstraction begins without refinement
308 Vec_Bit_t * vUnmark = Vec_BitStart( Wlc_NtkObjNumMax(p) );
309 // set up parameters to run PDR
310 Pdr_Par_t PdrPars, * pPdrPars = &PdrPars;
311 Pdr_ManSetDefaultParams( pPdrPars );
312 pPdrPars->fUseAbs = 1; // use 'pdr -t' (on-the-fly abstraction)
313 pPdrPars->fCtgs = 1; // use 'pdr -nc' (improved generalization)
314 pPdrPars->fSkipDown = 0; // use 'pdr -nc' (improved generalization)
315 //pPdrPars->nRestLimit = 500; // reset queue or proof-obligations when it gets larger than this
316 pPdrPars->fVerbose = pPars->fPdrVerbose;
317 // perform refinement iterations
318 for ( nIters = 1; nIters < pPars->nIterMax; nIters++ )
319 {
320 Aig_Man_t * pAig;
321 Abc_Cex_t * pCex;
322 Vec_Int_t * vPisNew, * vRefine;
323 Gia_Man_t * pGia, * pTemp;
324 Wlc_Ntk_t * pAbs;
325
326 if ( pPars->fVerbose )
327 printf( "\nIteration %d:\n", nIters );
328
329 // get abstracted GIA and the set of pseudo-PIs (vPisNew)
330 pAbs = Wlc_NtkAbs( p, pPars, vUnmark, &vPisNew, pPars->fVerbose );
331 pGia = Wlc_NtkBitBlast( pAbs, NULL );
332
333 // if the abstraction has flops with DC-init state,
334 // new PIs were introduced by bit-blasting at the end of the PI list
335 // here we move these variables to be *before* PPIs, because
336 // PPIs are supposed to be at the end of the PI list for refinement
337 nDcFlops = Wlc_NtkDcFlopNum(pAbs);
338 if ( nDcFlops > 0 ) // DC-init flops are present
339 {
340 pGia = Gia_ManPermuteInputs( pTemp = pGia, Wlc_NtkCountObjBits(p, vPisNew), nDcFlops );
341 Gia_ManStop( pTemp );
342 }
343 // if the word-level outputs have to be XORs, this is a place to do it
344 if ( pPars->fXorOutput )
345 {
346 pGia = Gia_ManTransformMiter2( pTemp = pGia );
347 Gia_ManStop( pTemp );
348 }
349 if ( pPars->fVerbose )
350 {
351 printf( "Derived abstraction with %d objects and %d PPIs. Bit-blasted AIG stats are:\n", Wlc_NtkObjNum(pAbs), Vec_IntSize(vPisNew) );
352 Gia_ManPrintStats( pGia, NULL );
353 }
354 Wlc_NtkFree( pAbs );
355
356 // try to prove abstracted GIA by converting it to AIG and calling PDR
357 pAig = Gia_ManToAigSimple( pGia );
358 RetValue = Pdr_ManSolve( pAig, pPdrPars );
359 pCex = pAig->pSeqModel; pAig->pSeqModel = NULL;
360 Aig_ManStop( pAig );
361
362 // consider outcomes
363 if ( pCex == NULL )
364 {
365 assert( RetValue ); // proved or undecided
366 Gia_ManStop( pGia );
367 Vec_IntFree( vPisNew );
368 break;
369 }
370
371 // perform refinement
372 vRefine = Wlc_NtkAbsRefinement( p, pGia, pCex, vPisNew );
373 Gia_ManStop( pGia );
374 Vec_IntFree( vPisNew );
375 if ( vRefine == NULL ) // real CEX
376 {
377 Abc_CexFree( pCex ); // return CEX in the future
378 break;
379 }
380
381 // update the set of objects to be un-abstracted
382 nNodes = Wlc_NtkRemoveFromAbstraction( p, vRefine, vUnmark );
383 if ( pPars->fVerbose )
384 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 );
385 Vec_IntFree( vRefine );
386 Abc_CexFree( pCex );
387 }
388 Vec_BitFree( vUnmark );
389 // report the result
390 if ( pPars->fVerbose )
391 printf( "\n" );
392 printf( "Abstraction " );
393 if ( RetValue == 0 )
394 printf( "resulted in a real CEX" );
395 else if ( RetValue == 1 )
396 printf( "is successfully proved" );
397 else
398 printf( "timed out" );
399 printf( " after %d iterations. ", nIters );
400 Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
401 return RetValue;
402}
403
407
408
410
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void Aig_ManStop(Aig_Man_t *p)
Definition aigMan.c:187
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Definition aig.h:50
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
Abc_Cex_t * Bmc_CexCareMinimizeAig(Gia_Man_t *p, int nRealPis, Abc_Cex_t *pCex, int nTryCexes, int fCheck, int fVerbose)
Definition bmcCexCare.c:254
Cube * p
Definition exorList.c:222
Aig_Man_t * Gia_ManToAigSimple(Gia_Man_t *p)
Definition giaAig.c:408
void Gia_ManStop(Gia_Man_t *p)
Definition giaMan.c:82
Gia_Man_t * Gia_ManPermuteInputs(Gia_Man_t *p, int nPpis, int nExtra)
Definition giaDup.c:2758
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
Gia_Man_t * Gia_ManTransformMiter2(Gia_Man_t *p)
Definition giaDup.c:3409
void Gia_ManPrintStats(Gia_Man_t *p, Gps_Par_t *pPars)
Definition giaMan.c:495
void Pdr_ManSetDefaultParams(Pdr_Par_t *pPars)
MACRO DEFINITIONS ///.
Definition pdrCore.c:50
typedefABC_NAMESPACE_HEADER_START struct Pdr_Par_t_ Pdr_Par_t
INCLUDES ///.
Definition pdr.h:40
int Pdr_ManSolve(Aig_Man_t *p, Pdr_Par_t *pPars)
Definition pdrCore.c:1765
unsigned Type
Definition wlc.h:121
unsigned Mark
Definition wlc.h:123
int nBitsAdd
Definition wlc.h:181
int fXorOutput
Definition wlc.h:187
int nBitsMul
Definition wlc.h:182
int nIterMax
Definition wlc.h:185
int fPdrVerbose
Definition wlc.h:202
int fVerbose
Definition wlc.h:201
int nBitsMux
Definition wlc.h:183
int nBitsFlop
Definition wlc.h:184
void Abc_CexFree(Abc_Cex_t *p)
Definition utilCex.c:382
typedefABC_NAMESPACE_HEADER_START struct Abc_Cex_t_ Abc_Cex_t
INCLUDES ///.
Definition utilCex.h:39
#define assert(ex)
Definition util_old.h:213
typedefABC_NAMESPACE_HEADER_START struct Vec_Bit_t_ Vec_Bit_t
INCLUDES ///.
Definition vecBit.h:42
int Wlc_NtkAbsCore2(Wlc_Ntk_t *p, Wlc_Par_t *pPars)
Definition wlcAbs2.c:302
struct Wlc_Par_t_ Wlc_Par_t
Definition wlc.h:178
Wlc_Ntk_t * Wlc_NtkDupDfsAbs(Wlc_Ntk_t *p, Vec_Int_t *vPisOld, Vec_Int_t *vPisNew, Vec_Int_t *vFlops)
Definition wlcNtk.c:1055
Gia_Man_t * Wlc_NtkBitBlast(Wlc_Ntk_t *p, Wlc_BstPar_t *pPars)
Definition wlcBlast.c:1349
void Wlc_NtkCleanMarks(Wlc_Ntk_t *p)
Definition wlcNtk.c:1135
#define Wlc_NtkForEachObjVec(vVec, p, pObj, i)
Definition wlc.h:360
void Wlc_NtkFree(Wlc_Ntk_t *p)
Definition wlcNtk.c:253
void Wlc_NtkSetRefs(Wlc_Ntk_t *p)
Definition wlcNtk.c:1373
struct Wlc_Ntk_t_ Wlc_Ntk_t
Definition wlc.h:135
#define Wlc_NtkForEachObj(p, pObj, i)
MACRO DEFINITIONS ///.
Definition wlc.h:356
#define Wlc_ObjForEachFanin(pObj, iFanin, i)
Definition wlc.h:375
@ WLC_OBJ_ARI_MULTI
Definition wlc.h:90
@ WLC_OBJ_ARI_REM
Definition wlc.h:92
@ WLC_OBJ_ARI_SUB
Definition wlc.h:89
@ WLC_OBJ_ARI_DIVIDE
Definition wlc.h:91
@ WLC_OBJ_MUX
Definition wlc.h:53
@ WLC_OBJ_ARI_MINUS
Definition wlc.h:95
@ WLC_OBJ_ARI_MODULUS
Definition wlc.h:93
@ WLC_OBJ_ARI_ADD
Definition wlc.h:88
int Wlc_NtkCountObjBits(Wlc_Ntk_t *p, Vec_Int_t *vPisNew)
Definition wlcNtk.c:1395
struct Wlc_Obj_t_ Wlc_Obj_t
BASIC TYPES ///.
Definition wlc.h:118
#define Wlc_NtkForEachCo(p, pCo, i)
Definition wlc.h:368
int Wlc_NtkDcFlopNum(Wlc_Ntk_t *p)
Definition wlcNtk.c:1351