51DdNode * Abc_NtkInitStateVarMap( DdManager * dd,
Abc_Ntk_t * pNtk,
int fVerbose )
53 DdNode ** pbVarsX, ** pbVarsY;
54 DdNode * bTemp, * bProd, * bVar;
59 pbVarsX =
ABC_ALLOC( DdNode *, dd->size );
60 pbVarsY =
ABC_ALLOC( DdNode *, dd->size );
61 bProd =
b1; Cudd_Ref( bProd );
64 pbVarsX[i] = dd->vars[ Abc_NtkPiNum(pNtk) + i ];
65 pbVarsY[i] = dd->vars[ Abc_NtkCiNum(pNtk) + i ];
67 bVar = Cudd_NotCond( pbVarsX[i], !Abc_LatchIsInit1(pLatch) );
68 bProd = Cudd_bddAnd( dd, bTemp = bProd, bVar ); Cudd_Ref( bProd );
69 Cudd_RecursiveDeref( dd, bTemp );
71 Cudd_SetVarMap( dd, pbVarsX, pbVarsY, Abc_NtkLatchNum(pNtk) );
90DdNode ** Abc_NtkCreatePartitions( DdManager * dd,
Abc_Ntk_t * pNtk,
int fReorder,
int fVerbose )
98 assert( dd->size == Abc_NtkCiNum(pNtk) );
99 Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + Abc_NtkLatchNum(pNtk) - 1 );
103 Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
105 Cudd_AutodynDisable( dd );
108 pbParts =
ABC_ALLOC( DdNode *, Abc_NtkLatchNum(pNtk) );
111 bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i );
112 pbParts[i] = Cudd_bddXnor( dd, bVar, (DdNode *)Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) ); Cudd_Ref( pbParts[i] );
121 fprintf( stdout,
"BDD nodes in the partitions before reordering %d.\n", Cudd_SharingSize(pbParts,Abc_NtkLatchNum(pNtk)) );
122 Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 );
123 Cudd_AutodynDisable( dd );
125 fprintf( stdout,
"BDD nodes in the partitions after reordering %d.\n", Cudd_SharingSize(pbParts,Abc_NtkLatchNum(pNtk)) );
141DdNode * Abc_NtkComputeReachable( DdManager * dd,
Abc_Ntk_t * pNtk, DdNode ** pbParts, DdNode * bInitial, DdNode * bOutput,
int nBddMax,
int nIterMax,
int fPartition,
int fReorder,
int fVerbose )
143 int fInternalReorder = 0;
146 DdNode * bReached, * bCubeCs;
147 DdNode * bCurrent, * bNext = NULL, * bTemp;
150 int i, nIters, nBddSize;
151 int nThreshold = 10000;
155 pbVarsY =
ABC_ALLOC( DdNode *, dd->size );
157 pbVarsY[i] = dd->vars[ Abc_NtkCiNum(pNtk) + i ];
162 pTree =
Extra_bddImageStart( dd, bCubeCs, Abc_NtkLatchNum(pNtk), pbParts, Abc_NtkLatchNum(pNtk), pbVarsY, fVerbose );
164 pTree2 =
Extra_bddImageStart2( dd, bCubeCs, Abc_NtkLatchNum(pNtk), pbParts, Abc_NtkLatchNum(pNtk), pbVarsY, fVerbose );
166 Cudd_RecursiveDeref( dd, bCubeCs );
169 bCurrent = bInitial; Cudd_Ref( bCurrent );
170 bReached = bInitial; Cudd_Ref( bReached );
172 for ( nIters = 1; nIters <= nIterMax; nIters++ )
180 Cudd_RecursiveDeref( dd, bCurrent );
182 bNext = Cudd_bddVarMap( dd, bTemp = bNext ); Cudd_Ref( bNext );
183 Cudd_RecursiveDeref( dd, bTemp );
185 if ( Cudd_bddLeq( dd, bNext, bReached ) )
188 nBddSize = Cudd_DagSize(bNext);
189 if ( nBddSize > nBddMax )
192 if ( !Cudd_bddLeq( dd, bNext, Cudd_Not(bOutput) ) )
194 printf(
"The miter is proved REACHABLE in %d iterations. ", nIters );
195 Cudd_RecursiveDeref( dd, bReached );
200 bCurrent = Cudd_bddAnd( dd, bNext, Cudd_Not(bReached) ); Cudd_Ref( bCurrent );
205 bReached = Cudd_bddOr( dd, bTemp = bReached, bNext ); Cudd_Ref( bReached );
206 Cudd_RecursiveDeref( dd, bTemp );
207 Cudd_RecursiveDeref( dd, bNext );
209 fprintf( stdout,
"Iteration = %3d. BDD = %5d. ", nIters, nBddSize );
210 if ( fInternalReorder && fReorder && nBddSize > nThreshold )
213 fprintf( stdout,
"Reordering... Before = %5d. ", Cudd_DagSize(bReached) );
214 Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 );
215 Cudd_AutodynDisable( dd );
217 fprintf( stdout,
"After = %5d.\r", Cudd_DagSize(bReached) );
221 fprintf( stdout,
"\r" );
223 Cudd_RecursiveDeref( dd, bNext );
229 if ( bReached == NULL )
234 double nMints = Cudd_CountMinterm(dd, bReached, Abc_NtkLatchNum(pNtk) );
235 if ( nIters > nIterMax || Cudd_DagSize(bReached) > nBddMax )
236 fprintf( stdout,
"Reachability analysis is stopped after %d iterations.\n", nIters );
238 fprintf( stdout,
"Reachability analysis completed in %d iterations.\n", nIters );
239 fprintf( stdout,
"Reachable states = %.0f. (Ratio = %.4f %%)\n", nMints, 100.0*nMints/pow(2.0, Abc_NtkLatchNum(pNtk)) );
243 Cudd_Deref( bReached );
244 if ( nIters > nIterMax || Cudd_DagSize(bReached) > nBddMax )
245 printf(
"Verified ONLY FOR STATES REACHED in %d iterations. \n", nIters );
246 printf(
"The miter is proved unreachable in %d iteration. ", nIters );
261void Abc_NtkVerifyUsingBdds(
Abc_Ntk_t * pNtk,
int nBddMax,
int nIterMax,
int fPartition,
int fReorder,
int fVerbose )
265 DdNode * bOutput, * bReached, * bInitial;
269 assert( Abc_NtkIsStrash(pNtk) );
270 assert( Abc_NtkPoNum(pNtk) == 1 );
271 assert( Abc_ObjFanoutNum(Abc_NtkPo(pNtk,0)) == 0 );
277 printf(
"The number of intermediate BDD nodes exceeded the limit (%d).\n", nBddMax );
281 printf(
"Shared BDD size is %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
284 bOutput = (DdNode *)Abc_ObjGlobalBdd(Abc_NtkPo(pNtk,0)); Cudd_Ref( bOutput );
287 pbParts = Abc_NtkCreatePartitions( dd, pNtk, fReorder, fVerbose );
290 bInitial = Abc_NtkInitStateVarMap( dd, pNtk, fVerbose ); Cudd_Ref( bInitial );
293 if ( !Cudd_bddLeq( dd, bInitial, Cudd_Not(bOutput) ) )
294 printf(
"The miter is proved REACHABLE in the initial state. " );
298 bReached = Abc_NtkComputeReachable( dd, pNtk, pbParts, bInitial, bOutput, nBddMax, nIterMax, fPartition, fReorder, fVerbose );
299 if ( bReached != NULL )
301 Cudd_Ref( bReached );
302 Cudd_RecursiveDeref( dd, bReached );
307 Cudd_RecursiveDeref( dd, bOutput );
308 Cudd_RecursiveDeref( dd, bInitial );
309 for ( i = 0; i < Abc_NtkLatchNum(pNtk); i++ )
310 Cudd_RecursiveDeref( dd, pbParts[i] );
315 ABC_PRT(
"Time", Abc_Clock() - clk );
struct Abc_Obj_t_ Abc_Obj_t
#define Abc_NtkForEachLatch(pNtk, pObj, i)
struct Abc_Ntk_t_ Abc_Ntk_t
ABC_DLL void * Abc_NtkFreeGlobalBdds(Abc_Ntk_t *pNtk, int fFreeMan)
ABC_DLL void * Abc_NtkBuildGlobalBdds(Abc_Ntk_t *pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose)
#define ABC_ALLOC(type, num)
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END