ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
abcUnreach.c
Go to the documentation of this file.
1
20
21#include "base/abc/abc.h"
22
23#ifdef ABC_USE_CUDD
24#include "bdd/extrab/extraBdd.h"
25#endif
26
28
29
33
34#ifdef ABC_USE_CUDD
35
36static DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose );
37static DdNode * Abc_NtkInitStateAndVarMap( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose );
38static DdNode * Abc_NtkComputeUnreachable( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bRelation, DdNode * bInitial, int fVerbose );
39static Abc_Ntk_t * Abc_NtkConstructExdc ( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUnreach );
40
44
56int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, int fVerbose )
57{
58 int fReorder = 1;
59 DdManager * dd;
60 DdNode * bRelation, * bInitial, * bUnreach;
61
62 // remove EXDC network if present
63 if ( pNtk->pExdc )
64 {
65 Abc_NtkDelete( pNtk->pExdc );
66 pNtk->pExdc = NULL;
67 }
68
69 // compute the global BDDs of the latches
70 dd = (DdManager *)Abc_NtkBuildGlobalBdds( pNtk, 10000000, 1, 1, 0, fVerbose );
71 if ( dd == NULL )
72 return 0;
73 if ( fVerbose )
74 printf( "Shared BDD size = %6d nodes.\n", Cudd_ReadKeys(dd) - Cudd_ReadDead(dd) );
75
76 // create the transition relation (dereferenced global BDDs)
77 bRelation = Abc_NtkTransitionRelation( dd, pNtk, fVerbose ); Cudd_Ref( bRelation );
78 // create the initial state and the variable map
79 bInitial = Abc_NtkInitStateAndVarMap( dd, pNtk, fVerbose ); Cudd_Ref( bInitial );
80 // compute the unreachable states
81 bUnreach = Abc_NtkComputeUnreachable( dd, pNtk, bRelation, bInitial, fVerbose ); Cudd_Ref( bUnreach );
82 Cudd_RecursiveDeref( dd, bRelation );
83 Cudd_RecursiveDeref( dd, bInitial );
84
85 // reorder and disable reordering
86 if ( fReorder )
87 {
88 if ( fVerbose )
89 fprintf( stdout, "BDD nodes in the unreachable states before reordering %d.\n", Cudd_DagSize(bUnreach) );
90 Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 );
91 Cudd_AutodynDisable( dd );
92 if ( fVerbose )
93 fprintf( stdout, "BDD nodes in the unreachable states after reordering %d.\n", Cudd_DagSize(bUnreach) );
94 }
95
96 // allocate ZDD variables
97 Cudd_zddVarsFromBddVars( dd, 2 );
98 // create the EXDC network representing the unreachable states
99 if ( pNtk->pExdc )
100 Abc_NtkDelete( pNtk->pExdc );
101 pNtk->pExdc = Abc_NtkConstructExdc( dd, pNtk, bUnreach );
102 Cudd_RecursiveDeref( dd, bUnreach );
103 Extra_StopManager( dd );
104// pNtk->pManGlob = NULL;
105
106 // make sure that everything is okay
107 if ( pNtk->pExdc && !Abc_NtkCheck( pNtk->pExdc ) )
108 {
109 printf( "Abc_NtkExtractSequentialDcs: The network check has failed.\n" );
110 Abc_NtkDelete( pNtk->pExdc );
111 return 0;
112 }
113 return 1;
114}
115
127DdNode * Abc_NtkTransitionRelation( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose )
128{
129 DdNode * bRel, * bTemp, * bProd, * bVar, * bInputs;
130 Abc_Obj_t * pNode;
131 int fReorder = 1;
132 int i;
133
134 // extand the BDD manager to represent NS variables
135 assert( dd->size == Abc_NtkCiNum(pNtk) );
136 Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + Abc_NtkLatchNum(pNtk) - 1 );
137
138 // enable reordering
139 if ( fReorder )
140 Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
141 else
142 Cudd_AutodynDisable( dd );
143
144 // compute the transition relation
145 bRel = b1; Cudd_Ref( bRel );
146 Abc_NtkForEachLatch( pNtk, pNode, i )
147 {
148 bVar = Cudd_bddIthVar( dd, Abc_NtkCiNum(pNtk) + i );
149// bProd = Cudd_bddXnor( dd, bVar, pNtk->vFuncsGlob->pArray[i] ); Cudd_Ref( bProd );
150 bProd = Cudd_bddXnor( dd, bVar, (DdNode *)Abc_ObjGlobalBdd(Abc_ObjFanin0(pNode)) ); Cudd_Ref( bProd );
151 bRel = Cudd_bddAnd( dd, bTemp = bRel, bProd ); Cudd_Ref( bRel );
152 Cudd_RecursiveDeref( dd, bTemp );
153 Cudd_RecursiveDeref( dd, bProd );
154 }
155 // free the global BDDs
156// Abc_NtkFreeGlobalBdds( pNtk );
157 Abc_NtkFreeGlobalBdds( pNtk, 0 );
158
159 // quantify the PI variables
160 bInputs = Extra_bddComputeRangeCube( dd, 0, Abc_NtkPiNum(pNtk) ); Cudd_Ref( bInputs );
161 bRel = Cudd_bddExistAbstract( dd, bTemp = bRel, bInputs ); Cudd_Ref( bRel );
162 Cudd_RecursiveDeref( dd, bTemp );
163 Cudd_RecursiveDeref( dd, bInputs );
164
165 // reorder and disable reordering
166 if ( fReorder )
167 {
168 if ( fVerbose )
169 fprintf( stdout, "BDD nodes in the transition relation before reordering %d.\n", Cudd_DagSize(bRel) );
170 Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 100 );
171 Cudd_AutodynDisable( dd );
172 if ( fVerbose )
173 fprintf( stdout, "BDD nodes in the transition relation after reordering %d.\n", Cudd_DagSize(bRel) );
174 }
175 Cudd_Deref( bRel );
176 return bRel;
177}
178
190DdNode * Abc_NtkInitStateAndVarMap( DdManager * dd, Abc_Ntk_t * pNtk, int fVerbose )
191{
192 DdNode ** pbVarsX, ** pbVarsY;
193 DdNode * bTemp, * bProd, * bVar;
194 Abc_Obj_t * pLatch;
195 int i;
196
197 // set the variable mapping for Cudd_bddVarMap()
198 pbVarsX = ABC_ALLOC( DdNode *, dd->size );
199 pbVarsY = ABC_ALLOC( DdNode *, dd->size );
200 bProd = b1; Cudd_Ref( bProd );
201 Abc_NtkForEachLatch( pNtk, pLatch, i )
202 {
203 pbVarsX[i] = dd->vars[ Abc_NtkPiNum(pNtk) + i ];
204 pbVarsY[i] = dd->vars[ Abc_NtkCiNum(pNtk) + i ];
205 // get the initial value of the latch
206 bVar = Cudd_NotCond( pbVarsX[i], !Abc_LatchIsInit1(pLatch) );
207 bProd = Cudd_bddAnd( dd, bTemp = bProd, bVar ); Cudd_Ref( bProd );
208 Cudd_RecursiveDeref( dd, bTemp );
209 }
210 Cudd_SetVarMap( dd, pbVarsX, pbVarsY, Abc_NtkLatchNum(pNtk) );
211 ABC_FREE( pbVarsX );
212 ABC_FREE( pbVarsY );
213
214 Cudd_Deref( bProd );
215 return bProd;
216}
217
229DdNode * Abc_NtkComputeUnreachable( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bTrans, DdNode * bInitial, int fVerbose )
230{
231 DdNode * bRelation, * bReached, * bCubeCs;
232 DdNode * bCurrent, * bNext, * bTemp;
233 int nIters, nMints;
234
235 // perform reachability analisys
236 bCurrent = bInitial; Cudd_Ref( bCurrent );
237 bReached = bInitial; Cudd_Ref( bReached );
238 bRelation = bTrans; Cudd_Ref( bRelation );
239 bCubeCs = Extra_bddComputeRangeCube( dd, Abc_NtkPiNum(pNtk), Abc_NtkCiNum(pNtk) ); Cudd_Ref( bCubeCs );
240 for ( nIters = 1; ; nIters++ )
241 {
242 // compute the next states
243 bNext = Cudd_bddAndAbstract( dd, bRelation, bCurrent, bCubeCs ); Cudd_Ref( bNext );
244 Cudd_RecursiveDeref( dd, bCurrent );
245 // remap these states into the current state vars
246 bNext = Cudd_bddVarMap( dd, bTemp = bNext ); Cudd_Ref( bNext );
247 Cudd_RecursiveDeref( dd, bTemp );
248 // check if there are any new states
249 if ( Cudd_bddLeq( dd, bNext, bReached ) )
250 break;
251 // get the new states
252 bCurrent = Cudd_bddAnd( dd, bNext, Cudd_Not(bReached) ); Cudd_Ref( bCurrent );
253 // minimize the new states with the reached states
254// bCurrent = Cudd_bddConstrain( dd, bTemp = bCurrent, Cudd_Not(bReached) ); Cudd_Ref( bCurrent );
255// Cudd_RecursiveDeref( dd, bTemp );
256 // add to the reached states
257 bReached = Cudd_bddOr( dd, bTemp = bReached, bNext ); Cudd_Ref( bReached );
258 Cudd_RecursiveDeref( dd, bTemp );
259 Cudd_RecursiveDeref( dd, bNext );
260 // minimize the transition relation
261// bRelation = Cudd_bddConstrain( dd, bTemp = bRelation, Cudd_Not(bReached) ); Cudd_Ref( bRelation );
262// Cudd_RecursiveDeref( dd, bTemp );
263 }
264 Cudd_RecursiveDeref( dd, bRelation );
265 Cudd_RecursiveDeref( dd, bCubeCs );
266 Cudd_RecursiveDeref( dd, bNext );
267 // report the stats
268 if ( fVerbose )
269 {
270 nMints = (int)Cudd_CountMinterm(dd, bReached, Abc_NtkLatchNum(pNtk) );
271 fprintf( stdout, "Reachability analysis completed in %d iterations.\n", nIters );
272 fprintf( stdout, "The number of minterms in the reachable state set = %d. (%6.2f %%)\n", nMints, 100.0*nMints/(1<<Abc_NtkLatchNum(pNtk)) );
273 }
274//ABC_PRB( dd, bReached );
275 Cudd_Deref( bReached );
276 return Cudd_Not( bReached );
277}
278
290Abc_Ntk_t * Abc_NtkConstructExdc( DdManager * dd, Abc_Ntk_t * pNtk, DdNode * bUnreach )
291{
292 Abc_Ntk_t * pNtkNew;
293 Abc_Obj_t * pNode, * pNodeNew;
294 int * pPermute;
295 int i;
296
297 // start the new network
298 pNtkNew = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_BDD, 1 );
299 pNtkNew->pName = Extra_UtilStrsav( "exdc" );
300 pNtkNew->pSpec = NULL;
301
302 // create PIs corresponding to LOs
303 Abc_NtkForEachLatchOutput( pNtk, pNode, i )
304 Abc_ObjAssignName( pNode->pCopy = Abc_NtkCreatePi(pNtkNew), Abc_ObjName(pNode), NULL );
305 // cannot ADD POs here because pLatch->pCopy point to the PIs
306
307 // create a new node
308 pNodeNew = Abc_NtkCreateNode(pNtkNew);
309 // add the fanins corresponding to latch outputs
310 Abc_NtkForEachLatchOutput( pNtk, pNode, i )
311 Abc_ObjAddFanin( pNodeNew, pNode->pCopy );
312
313 // create the logic function
314 pPermute = ABC_ALLOC( int, dd->size );
315 for ( i = 0; i < dd->size; i++ )
316 pPermute[i] = -1;
317 Abc_NtkForEachLatch( pNtk, pNode, i )
318 pPermute[Abc_NtkPiNum(pNtk) + i] = i;
319 // remap the functions
320 pNodeNew->pData = Extra_TransferPermute( dd, (DdManager *)pNtkNew->pManFunc, bUnreach, pPermute ); Cudd_Ref( (DdNode *)pNodeNew->pData );
321 ABC_FREE( pPermute );
322 Abc_NodeMinimumBase( pNodeNew );
323
324 // for each CO, create PO (skip POs equal to CIs because of name conflict)
325 Abc_NtkForEachPo( pNtk, pNode, i )
326 if ( !Abc_ObjIsCi(Abc_ObjFanin0(pNode)) )
327 Abc_ObjAssignName( pNode->pCopy = Abc_NtkCreatePo(pNtkNew), Abc_ObjName(pNode), NULL );
328 Abc_NtkForEachLatchInput( pNtk, pNode, i )
329 Abc_ObjAssignName( pNode->pCopy = Abc_NtkCreatePo(pNtkNew), Abc_ObjName(pNode), NULL );
330
331 // link to the POs of the network
332 Abc_NtkForEachPo( pNtk, pNode, i )
333 if ( !Abc_ObjIsCi(Abc_ObjFanin0(pNode)) )
334 Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
335 Abc_NtkForEachLatchInput( pNtk, pNode, i )
336 Abc_ObjAddFanin( pNode->pCopy, pNodeNew );
337
338 // remove the extra nodes
339 Abc_AigCleanup( (Abc_Aig_t *)pNtkNew->pManFunc );
340
341 // fix the problem with complemented and duplicated CO edges
342 Abc_NtkLogicMakeSimpleCos( pNtkNew, 0 );
343
344 // transform the network to the SOP representation
345 if ( !Abc_NtkBddToSop( pNtkNew, -1, ABC_INFINITY, 1 ) )
346 {
347 printf( "Abc_NtkConstructExdc(): Converting to SOPs has failed.\n" );
348 return NULL;
349 }
350 return pNtkNew;
351// return NULL;
352}
353
354#else
355
356int Abc_NtkExtractSequentialDcs( Abc_Ntk_t * pNtk, int fVerbose ) { return 1; }
357
358#endif
359
363
364
366
ABC_NAMESPACE_IMPL_START int Abc_NtkExtractSequentialDcs(Abc_Ntk_t *pNtk, int fVerbose)
DECLARATIONS ///.
Definition abcUnreach.c:356
struct Abc_Obj_t_ Abc_Obj_t
Definition abc.h:116
ABC_DLL Abc_Ntk_t * Abc_NtkAlloc(Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan)
DECLARATIONS ///.
Definition abcNtk.c:53
ABC_DLL void Abc_ObjAddFanin(Abc_Obj_t *pObj, Abc_Obj_t *pFanin)
Definition abcFanio.c:84
#define Abc_NtkForEachPo(pNtk, pPo, i)
Definition abc.h:520
#define Abc_NtkForEachLatch(pNtk, pObj, i)
Definition abc.h:500
ABC_DLL int Abc_NtkCheck(Abc_Ntk_t *pNtk)
FUNCTION DEFINITIONS ///.
Definition abcCheck.c:64
struct Abc_Aig_t_ Abc_Aig_t
Definition abc.h:117
ABC_DLL char * Abc_ObjName(Abc_Obj_t *pNode)
DECLARATIONS ///.
Definition abcNames.c:49
struct Abc_Ntk_t_ Abc_Ntk_t
Definition abc.h:115
ABC_DLL char * Abc_ObjAssignName(Abc_Obj_t *pObj, char *pName, char *pSuffix)
Definition abcNames.c:69
@ ABC_NTK_LOGIC
Definition abc.h:57
ABC_DLL void * Abc_NtkFreeGlobalBdds(Abc_Ntk_t *pNtk, int fFreeMan)
#define Abc_NtkForEachLatchOutput(pNtk, pObj, i)
Definition abc.h:506
ABC_DLL int Abc_NtkLogicMakeSimpleCos(Abc_Ntk_t *pNtk, int fDuplicate)
Definition abcUtil.c:1080
ABC_DLL int Abc_AigCleanup(Abc_Aig_t *pMan)
Definition abcAig.c:194
#define Abc_NtkForEachLatchInput(pNtk, pObj, i)
Definition abc.h:503
ABC_DLL void * Abc_NtkBuildGlobalBdds(Abc_Ntk_t *pNtk, int fBddSizeMax, int fDropInternal, int fReorder, int fReverse, int fVerbose)
ABC_DLL void Abc_NtkDelete(Abc_Ntk_t *pNtk)
Definition abcNtk.c:1421
@ ABC_FUNC_BDD
Definition abc.h:66
ABC_DLL int Abc_NtkBddToSop(Abc_Ntk_t *pNtk, int fMode, int nCubeLimit, int fCubeSort)
Definition abcFunc.c:866
ABC_DLL int Abc_NodeMinimumBase(Abc_Obj_t *pNode)
Definition abcMinBase.c:893
#define ABC_ALLOC(type, num)
Definition abc_global.h:264
#define ABC_INFINITY
MACRO DEFINITIONS ///.
Definition abc_global.h:250
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define b1
Definition bbrImage.c:97
void Extra_StopManager(DdManager *dd)
DdNode * Extra_TransferPermute(DdManager *ddSource, DdManager *ddDestination, DdNode *f, int *Permute)
DdNode * Extra_bddComputeRangeCube(DdManager *dd, int iStart, int iStop)
char * Extra_UtilStrsav(const char *s)
char * pName
Definition abc.h:158
Abc_Ntk_t * pExdc
Definition abc.h:201
void * pManFunc
Definition abc.h:191
char * pSpec
Definition abc.h:159
void * pData
Definition abc.h:145
Abc_Obj_t * pCopy
Definition abc.h:148
#define assert(ex)
Definition util_old.h:213