abc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
abcReach.c File Reference
#include "base/abc/abc.h"
#include "misc/extra/extraBdd.h"

Go to the source code of this file.

Functions

ABC_NAMESPACE_IMPL_START DdNodeAbc_NtkInitStateVarMap (DdManager *dd, Abc_Ntk_t *pNtk, int fVerbose)
 DECLARATIONS ///. More...
 
DdNode ** Abc_NtkCreatePartitions (DdManager *dd, Abc_Ntk_t *pNtk, int fReorder, int fVerbose)
 
DdNodeAbc_NtkComputeReachable (DdManager *dd, Abc_Ntk_t *pNtk, DdNode **pbParts, DdNode *bInitial, DdNode *bOutput, int nBddMax, int nIterMax, int fPartition, int fReorder, int fVerbose)
 
void Abc_NtkVerifyUsingBdds (Abc_Ntk_t *pNtk, int nBddMax, int nIterMax, int fPartition, int fReorder, int fVerbose)
 

Function Documentation

DdNode* Abc_NtkComputeReachable ( DdManager dd,
Abc_Ntk_t pNtk,
DdNode **  pbParts,
DdNode bInitial,
DdNode bOutput,
int  nBddMax,
int  nIterMax,
int  fPartition,
int  fReorder,
int  fVerbose 
)

Function*************************************************************

Synopsis [Computes the set of unreachable states.]

Description []

SideEffects []

SeeAlso []

Definition at line 136 of file abcReach.c.

137 {
138  int fInternalReorder = 0;
139  Extra_ImageTree_t * pTree = NULL;
140  Extra_ImageTree2_t * pTree2 = NULL;
141  DdNode * bReached, * bCubeCs;
142  DdNode * bCurrent, * bNext = NULL, * bTemp;
143  DdNode ** pbVarsY;
144  Abc_Obj_t * pLatch;
145  int i, nIters, nBddSize;
146  int nThreshold = 10000;
147 
148  // collect the NS variables
149  // set the variable mapping for Cudd_bddVarMap()
150  pbVarsY = ABC_ALLOC( DdNode *, dd->size );
151  Abc_NtkForEachLatch( pNtk, pLatch, i )
152  pbVarsY[i] = dd->vars[ Abc_NtkCiNum(pNtk) + i ];
153 
154  // start the image computation
155  bCubeCs = Extra_bddComputeRangeCube( dd, Abc_NtkPiNum(pNtk), Abc_NtkCiNum(pNtk) ); Cudd_Ref( bCubeCs );
156  if ( fPartition )
157  pTree = Extra_bddImageStart( dd, bCubeCs, Abc_NtkLatchNum(pNtk), pbParts, Abc_NtkLatchNum(pNtk), pbVarsY, fVerbose );
158  else
159  pTree2 = Extra_bddImageStart2( dd, bCubeCs, Abc_NtkLatchNum(pNtk), pbParts, Abc_NtkLatchNum(pNtk), pbVarsY, fVerbose );
160  ABC_FREE( pbVarsY );
161  Cudd_RecursiveDeref( dd, bCubeCs );
162 
163  // perform reachability analisys
164  bCurrent = bInitial; Cudd_Ref( bCurrent );
165  bReached = bInitial; Cudd_Ref( bReached );
166  assert( nIterMax > 1 ); // required to not deref uninitialized bNext
167  for ( nIters = 1; nIters <= nIterMax; nIters++ )
168  {
169  // compute the next states
170  if ( fPartition )
171  bNext = Extra_bddImageCompute( pTree, bCurrent );
172  else
173  bNext = Extra_bddImageCompute2( pTree2, bCurrent );
174  Cudd_Ref( bNext );
175  Cudd_RecursiveDeref( dd, bCurrent );
176  // remap these states into the current state vars
177  bNext = Cudd_bddVarMap( dd, bTemp = bNext ); Cudd_Ref( bNext );
178  Cudd_RecursiveDeref( dd, bTemp );
179  // check if there are any new states
180  if ( Cudd_bddLeq( dd, bNext, bReached ) )
181  break;
182  // check the BDD size
183  nBddSize = Cudd_DagSize(bNext);
184  if ( nBddSize > nBddMax )
185  break;
186  // check the result
187  if ( !Cudd_bddLeq( dd, bNext, Cudd_Not(bOutput) ) )
188  {
189  printf( "The miter is proved REACHABLE in %d iterations. ", nIters );
190  Cudd_RecursiveDeref( dd, bReached );
191  bReached = NULL;
192  break;
193  }
194  // get the new states
195  bCurrent = Cudd_bddAnd( dd, bNext, Cudd_Not(bReached) ); Cudd_Ref( bCurrent );
196  // minimize the new states with the reached states
197 // bCurrent = Cudd_bddConstrain( dd, bTemp = bCurrent, Cudd_Not(bReached) ); Cudd_Ref( bCurrent );
198 // Cudd_RecursiveDeref( dd, bTemp );
199  // add to the reached states
200  bReached = Cudd_bddOr( dd, bTemp = bReached, bNext ); Cudd_Ref( bReached );
201  Cudd_RecursiveDeref( dd, bTemp );
202  Cudd_RecursiveDeref( dd, bNext );
203  if ( fVerbose )
204  fprintf( stdout, "Iteration = %3d. BDD = %5d. ", nIters, nBddSize );
205  if ( fInternalReorder && fReorder && nBddSize > nThreshold )
206  {
207  if ( fVerbose )
208  fprintf( stdout, "Reordering... Before = %5d. ", Cudd_DagSize(bReached) );
210  Cudd_AutodynDisable( dd );
211  if ( fVerbose )
212  fprintf( stdout, "After = %5d.\r", Cudd_DagSize(bReached) );
213  nThreshold *= 2;
214  }
215  if ( fVerbose )
216  fprintf( stdout, "\r" );
217  }
218  Cudd_RecursiveDeref( dd, bNext );
219  // undo the image tree
220  if ( fPartition )
221  Extra_bddImageTreeDelete( pTree );
222  else
223  Extra_bddImageTreeDelete2( pTree2 );
224  if ( bReached == NULL )
225  return NULL;
226  // report the stats
227  if ( fVerbose )
228  {
229  double nMints = Cudd_CountMinterm(dd, bReached, Abc_NtkLatchNum(pNtk) );
230  if ( nIters > nIterMax || Cudd_DagSize(bReached) > nBddMax )
231  fprintf( stdout, "Reachability analysis is stopped after %d iterations.\n", nIters );
232  else
233  fprintf( stdout, "Reachability analysis completed in %d iterations.\n", nIters );
234  fprintf( stdout, "Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Abc_NtkLatchNum(pNtk)) );
235  fflush( stdout );
236  }
237 //ABC_PRB( dd, bReached );
238  Cudd_Deref( bReached );
239  if ( nIters > nIterMax || Cudd_DagSize(bReached) > nBddMax )
240  printf( "Verified ONLY FOR STATES REACHED in %d iterations. \n", nIters );
241  printf( "The miter is proved unreachable in %d iteration. ", nIters );
242  return bReached;
243 }
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
double Cudd_CountMinterm(DdManager *manager, DdNode *node, int nvars)
Definition: cuddUtil.c:578
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
int size
Definition: cuddInt.h:361
static int Abc_NtkLatchNum(Abc_Ntk_t *pNtk)
Definition: abc.h:294
void Extra_bddImageTreeDelete2(Extra_ImageTree2_t *pTree)
static int Abc_NtkCiNum(Abc_Ntk_t *pNtk)
Definition: abc.h:287
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
void Extra_bddImageTreeDelete(Extra_ImageTree_t *pTree)
for(p=first;p->value< newval;p=p->next)
Extra_ImageTree_t * Extra_bddImageStart(DdManager *dd, DdNode *bCare, int nParts, DdNode **pbParts, int nVars, DdNode **pbVars, int fVerbose)
DdNode * Cudd_bddVarMap(DdManager *manager, DdNode *f)
Definition: cuddCompose.c:373
DdNode * Extra_bddComputeRangeCube(DdManager *dd, int iStart, int iStop)
Definition: extraBddMisc.c:699
DdNode * Extra_bddImageCompute(Extra_ImageTree_t *pTree, DdNode *bCare)
if(last==0)
Definition: sparse_int.h:34
else
Definition: sparse_int.h:55
#define Abc_NtkForEachLatch(pNtk, pObj, i)
Definition: abc.h:497
DdNode * Cudd_bddOr(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:381
void Cudd_AutodynDisable(DdManager *unique)
Definition: cuddAPI.c:708
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int Abc_NtkPiNum(Abc_Ntk_t *pNtk)
Definition: abc.h:285
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:314
#define assert(ex)
Definition: util_old.h:213
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddReorder.c:176
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
DdNode * Extra_bddImageCompute2(Extra_ImageTree2_t *pTree, DdNode *bCare)
Extra_ImageTree2_t * Extra_bddImageStart2(DdManager *dd, DdNode *bCare, int nParts, DdNode **pbParts, int nVars, DdNode **pbVars, int fVerbose)
int Cudd_DagSize(DdNode *node)
Definition: cuddUtil.c:442
DdNode** Abc_NtkCreatePartitions ( DdManager dd,
Abc_Ntk_t pNtk,
int  fReorder,
int  fVerbose 
)

Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 85 of file abcReach.c.

86 {
87  DdNode ** pbParts;
88  DdNode * bVar;
89  Abc_Obj_t * pNode;
90  int i;
91 
92  // extand the BDD manager to represent NS variables
93  assert( dd->size == Abc_NtkCiNum(pNtk) );
94  Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + Abc_NtkLatchNum(pNtk) - 1 );
95 
96  // enable reordering
97  if ( fReorder )
99  else
100  Cudd_AutodynDisable( dd );
101 
102  // compute the transition relation
103  pbParts = ABC_ALLOC( DdNode *, Abc_NtkLatchNum(pNtk) );
104  Abc_NtkForEachLatch( pNtk, pNode, i )
105  {
106  bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i );
107  pbParts[i] = Cudd_bddXnor( dd, bVar, (DdNode *)Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) ); Cudd_Ref( pbParts[i] );
108  }
109  // free the global BDDs
110  Abc_NtkFreeGlobalBdds( pNtk, 0 );
111 
112  // reorder and disable reordering
113  if ( fReorder )
114  {
115  if ( fVerbose )
116  fprintf( stdout, "BDD nodes in the partitions before reordering %d.\n", Cudd_SharingSize(pbParts,Abc_NtkLatchNum(pNtk)) );
118  Cudd_AutodynDisable( dd );
119  if ( fVerbose )
120  fprintf( stdout, "BDD nodes in the partitions after reordering %d.\n", Cudd_SharingSize(pbParts,Abc_NtkLatchNum(pNtk)) );
121  }
122  return pbParts;
123 }
Definition: cudd.h:278
int size
Definition: cuddInt.h:361
static int Abc_NtkLatchNum(Abc_Ntk_t *pNtk)
Definition: abc.h:294
static int Abc_NtkCiNum(Abc_Ntk_t *pNtk)
Definition: abc.h:287
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
static Abc_Obj_t * Abc_ObjFanin0(Abc_Obj_t *pObj)
Definition: abc.h:373
static void * Abc_ObjGlobalBdd(Abc_Obj_t *pObj)
Definition: abc.h:431
ABC_DLL void * Abc_NtkFreeGlobalBdds(Abc_Ntk_t *pNtk, int fFreeMan)
Definition: abcNtbdd.c:476
#define Abc_NtkForEachLatch(pNtk, pObj, i)
Definition: abc.h:497
DdNode * Cudd_bddXnor(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:507
void Cudd_AutodynDisable(DdManager *unique)
Definition: cuddAPI.c:708
DdNode * Cudd_bddIthVar(DdManager *dd, int i)
Definition: cuddAPI.c:416
#define assert(ex)
Definition: util_old.h:213
int Cudd_ReduceHeap(DdManager *table, Cudd_ReorderingType heuristic, int minsize)
Definition: cuddReorder.c:176
void Cudd_AutodynEnable(DdManager *unique, Cudd_ReorderingType method)
Definition: cuddAPI.c:669
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
int Cudd_SharingSize(DdNode **nodeArray, int n)
Definition: cuddUtil.c:544
ABC_NAMESPACE_IMPL_START DdNode* Abc_NtkInitStateVarMap ( DdManager dd,
Abc_Ntk_t pNtk,
int  fVerbose 
)

DECLARATIONS ///.

CFile****************************************************************

FileName [abcReach.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [Network and node package.]

Synopsis [Performs reachability analysis.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - June 20, 2005.]

Revision [

Id:
abcReach.c,v 1.00 2005/06/20 00:00:00 alanmi Exp

]FUNCTION DEFINITIONS /// Function*************************************************************

Synopsis [Computes the initial state and sets up the variable map.]

Description []

SideEffects []

SeeAlso []

Definition at line 46 of file abcReach.c.

47 {
48  DdNode ** pbVarsX, ** pbVarsY;
49  DdNode * bTemp, * bProd, * bVar;
50  Abc_Obj_t * pLatch;
51  int i;
52 
53  // set the variable mapping for Cudd_bddVarMap()
54  pbVarsX = ABC_ALLOC( DdNode *, dd->size );
55  pbVarsY = ABC_ALLOC( DdNode *, dd->size );
56  bProd = b1; Cudd_Ref( bProd );
57  Abc_NtkForEachLatch( pNtk, pLatch, i )
58  {
59  pbVarsX[i] = dd->vars[ Abc_NtkPiNum(pNtk) + i ];
60  pbVarsY[i] = dd->vars[ Abc_NtkCiNum(pNtk) + i ];
61  // get the initial value of the latch
62  bVar = Cudd_NotCond( pbVarsX[i], !Abc_LatchIsInit1(pLatch) );
63  bProd = Cudd_bddAnd( dd, bTemp = bProd, bVar ); Cudd_Ref( bProd );
64  Cudd_RecursiveDeref( dd, bTemp );
65  }
66  Cudd_SetVarMap( dd, pbVarsX, pbVarsY, Abc_NtkLatchNum(pNtk) );
67  ABC_FREE( pbVarsX );
68  ABC_FREE( pbVarsY );
69 
70  Cudd_Deref( bProd );
71  return bProd;
72 }
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:438
int size
Definition: cuddInt.h:361
#define b1
Definition: extraBdd.h:76
int Cudd_SetVarMap(DdManager *manager, DdNode **x, DdNode **y, int n)
Definition: cuddCompose.c:416
static int Abc_NtkLatchNum(Abc_Ntk_t *pNtk)
Definition: abc.h:294
static int Abc_NtkCiNum(Abc_Ntk_t *pNtk)
Definition: abc.h:287
#define ABC_ALLOC(type, num)
Definition: abc_global.h:229
#define Abc_NtkForEachLatch(pNtk, pObj, i)
Definition: abc.h:497
static int Abc_LatchIsInit1(Abc_Obj_t *pLatch)
Definition: abc.h:423
#define ABC_FREE(obj)
Definition: abc_global.h:232
static int Abc_NtkPiNum(Abc_Ntk_t *pNtk)
Definition: abc.h:285
DdNode ** vars
Definition: cuddInt.h:390
#define Cudd_NotCond(node, c)
Definition: cudd.h:383
DdNode * Cudd_bddAnd(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:314
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
void Abc_NtkVerifyUsingBdds ( Abc_Ntk_t pNtk,
int  nBddMax,
int  nIterMax,
int  fPartition,
int  fReorder,
int  fVerbose 
)

Function*************************************************************

Synopsis [Performs reachability to see if any .]

Description []

SideEffects []

SeeAlso []

Definition at line 256 of file abcReach.c.

257 {
258  DdManager * dd;
259  DdNode ** pbParts;
260  DdNode * bOutput, * bReached, * bInitial;
261  int i;
262  abctime clk = Abc_Clock();
263 
264  assert( Abc_NtkIsStrash(pNtk) );
265  assert( Abc_NtkPoNum(pNtk) == 1 );
266  assert( Abc_ObjFanoutNum(Abc_NtkPo(pNtk,0)) == 0 ); // PO should go first
267 
268  // compute the global BDDs of the latches
269  dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, nBddMax, 1, fReorder, fVerbose );
270  if ( dd == NULL )
271  {
272  printf( "The number of intermediate BDD nodes exceeded the limit (%d).\n", nBddMax );
273  return;
274  }
275  if ( fVerbose )
276  printf( "Shared BDD size is %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
277 
278  // save the output BDD
279  bOutput = (DdNode *)Abc_ObjGlobalBdd(Abc_NtkPo(pNtk,0)); Cudd_Ref( bOutput );
280 
281  // create partitions
282  pbParts = Abc_NtkCreatePartitions( dd, pNtk, fReorder, fVerbose );
283 
284  // create the initial state and the variable map
285  bInitial = Abc_NtkInitStateVarMap( dd, pNtk, fVerbose ); Cudd_Ref( bInitial );
286 
287  // check the result
288  if ( !Cudd_bddLeq( dd, bInitial, Cudd_Not(bOutput) ) )
289  printf( "The miter is proved REACHABLE in the initial state. " );
290  else
291  {
292  // compute the reachable states
293  bReached = Abc_NtkComputeReachable( dd, pNtk, pbParts, bInitial, bOutput, nBddMax, nIterMax, fPartition, fReorder, fVerbose );
294  if ( bReached != NULL )
295  {
296  Cudd_Ref( bReached );
297  Cudd_RecursiveDeref( dd, bReached );
298  }
299  }
300 
301  // cleanup
302  Cudd_RecursiveDeref( dd, bOutput );
303  Cudd_RecursiveDeref( dd, bInitial );
304  for ( i = 0; i < Abc_NtkLatchNum(pNtk); i++ )
305  Cudd_RecursiveDeref( dd, pbParts[i] );
306  ABC_FREE( pbParts );
307  Extra_StopManager( dd );
308 
309  // report the runtime
310  ABC_PRT( "Time", Abc_Clock() - clk );
311  fflush( stdout );
312 }
static int Abc_NtkIsStrash(Abc_Ntk_t *pNtk)
Definition: abc.h:251
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:154
Definition: cudd.h:278
#define Cudd_Not(node)
Definition: cudd.h:367
static int Abc_ObjFanoutNum(Abc_Obj_t *pObj)
Definition: abc.h:365
static int Abc_NtkLatchNum(Abc_Ntk_t *pNtk)
Definition: abc.h:294
static abctime Abc_Clock()
Definition: abc_global.h:279
void Extra_StopManager(DdManager *dd)
Definition: extraBddMisc.c:223
static void * Abc_ObjGlobalBdd(Abc_Obj_t *pObj)
Definition: abc.h:431
DdNode ** Abc_NtkCreatePartitions(DdManager *dd, Abc_Ntk_t *pNtk, int fReorder, int fVerbose)
Definition: abcReach.c:85
ABC_NAMESPACE_IMPL_START DdNode * Abc_NtkInitStateVarMap(DdManager *dd, Abc_Ntk_t *pNtk, int fVerbose)
DECLARATIONS ///.
Definition: abcReach.c:46
int Cudd_bddLeq(DdManager *dd, DdNode *f, DdNode *g)
Definition: cuddBddIte.c:536
static Abc_Obj_t * Abc_NtkPo(Abc_Ntk_t *pNtk, int i)
Definition: abc.h:316
static int Abc_NtkPoNum(Abc_Ntk_t *pNtk)
Definition: abc.h:286
#define ABC_FREE(obj)
Definition: abc_global.h:232
#define ABC_PRT(a, t)
Definition: abc_global.h:220
unsigned int Cudd_ReadKeys(DdManager *dd)
Definition: cuddAPI.c:1626
DdNode * Abc_NtkComputeReachable(DdManager *dd, Abc_Ntk_t *pNtk, DdNode **pbParts, DdNode *bInitial, DdNode *bOutput, int nBddMax, int nIterMax, int fPartition, int fReorder, int fVerbose)
Definition: abcReach.c:136
#define assert(ex)
Definition: util_old.h:213
ABC_DLL void * Abc_NtkBuildGlobalBdds(Abc_Ntk_t *pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fVerbose)
Definition: abcNtbdd.c:251
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:129
unsigned int Cudd_ReadDead(DdManager *dd)
Definition: cuddAPI.c:1646
ABC_INT64_T abctime
Definition: abc_global.h:278