ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ivyDfs.c
Go to the documentation of this file.
1
20
21#include "ivy.h"
22
24
25
29
33
45void Ivy_ManDfs_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Int_t * vNodes )
46{
47 if ( Ivy_ObjIsMarkA(pObj) )
48 return;
49 Ivy_ObjSetMarkA(pObj);
50 if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsCi(pObj) )
51 {
52 if ( p->pHaig == NULL && pObj->pEquiv )
53 Ivy_ManDfs_rec( p, Ivy_Regular(pObj->pEquiv), vNodes );
54 return;
55 }
56//printf( "visiting node %d\n", pObj->Id );
57/*
58 if ( pObj->Id == 87 || pObj->Id == 90 )
59 {
60 int y = 0;
61 }
62*/
63 assert( Ivy_ObjIsBuf(pObj) || Ivy_ObjIsAnd(pObj) || Ivy_ObjIsExor(pObj) );
64 Ivy_ManDfs_rec( p, Ivy_ObjFanin0(pObj), vNodes );
65 if ( !Ivy_ObjIsBuf(pObj) )
66 Ivy_ManDfs_rec( p, Ivy_ObjFanin1(pObj), vNodes );
67 if ( p->pHaig == NULL && pObj->pEquiv )
68 Ivy_ManDfs_rec( p, Ivy_Regular(pObj->pEquiv), vNodes );
69 Vec_IntPush( vNodes, pObj->Id );
70
71//printf( "adding node %d with fanins %d and %d and equiv %d (refs = %d)\n",
72// pObj->Id, Ivy_ObjFanin0(pObj)->Id, Ivy_ObjFanin1(pObj)->Id,
73// pObj->pEquiv? Ivy_Regular(pObj->pEquiv)->Id: -1, Ivy_ObjRefs(pObj) );
74}
75
88{
89 Vec_Int_t * vNodes;
90 Ivy_Obj_t * pObj;
91 int i;
92 assert( Ivy_ManLatchNum(p) == 0 );
93 // make sure the nodes are not marked
94 Ivy_ManForEachObj( p, pObj, i )
95 assert( !pObj->fMarkA && !pObj->fMarkB );
96 // collect the nodes
97 vNodes = Vec_IntAlloc( Ivy_ManNodeNum(p) );
98 Ivy_ManForEachPo( p, pObj, i )
99 Ivy_ManDfs_rec( p, Ivy_ObjFanin0(pObj), vNodes );
100 // unmark the collected nodes
101// Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
102// Ivy_ObjClearMarkA(pObj);
103 Ivy_ManForEachObj( p, pObj, i )
104 Ivy_ObjClearMarkA(pObj);
105 // make sure network does not have dangling nodes
106 assert( Vec_IntSize(vNodes) == Ivy_ManNodeNum(p) + Ivy_ManBufNum(p) );
107 return vNodes;
108}
109
122{
123 Vec_Int_t * vNodes, * vLatches;
124 Ivy_Obj_t * pObj;
125 int i;
126// assert( Ivy_ManLatchNum(p) > 0 );
127 // make sure the nodes are not marked
128 Ivy_ManForEachObj( p, pObj, i )
129 assert( !pObj->fMarkA && !pObj->fMarkB );
130 // collect the latches
131 vLatches = Vec_IntAlloc( Ivy_ManLatchNum(p) );
132 Ivy_ManForEachLatch( p, pObj, i )
133 Vec_IntPush( vLatches, pObj->Id );
134 // collect the nodes
135 vNodes = Vec_IntAlloc( Ivy_ManNodeNum(p) );
136 Ivy_ManForEachPo( p, pObj, i )
137 Ivy_ManDfs_rec( p, Ivy_ObjFanin0(pObj), vNodes );
138 Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
139 Ivy_ManDfs_rec( p, Ivy_ObjFanin0(pObj), vNodes );
140 // unmark the collected nodes
141// Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
142// Ivy_ObjClearMarkA(pObj);
143 Ivy_ManForEachObj( p, pObj, i )
144 Ivy_ObjClearMarkA(pObj);
145 // make sure network does not have dangling nodes
146// assert( Vec_IntSize(vNodes) == Ivy_ManNodeNum(p) + Ivy_ManBufNum(p) );
147
148// temporary!!!
149
150 if ( pvLatches == NULL )
151 Vec_IntFree( vLatches );
152 else
153 *pvLatches = vLatches;
154 return vNodes;
155}
156
169{
170 if ( pObj->fMarkA )
171 return;
172 if ( Ivy_ObjIsBuf(pObj) )
173 {
174 Ivy_ManCollectCone_rec( Ivy_ObjFanin0(pObj), vCone );
175 Vec_PtrPush( vCone, pObj );
176 return;
177 }
178 assert( Ivy_ObjIsNode(pObj) );
179 Ivy_ManCollectCone_rec( Ivy_ObjFanin0(pObj), vCone );
180 Ivy_ManCollectCone_rec( Ivy_ObjFanin1(pObj), vCone );
181 Vec_PtrPushUnique( vCone, pObj );
182}
183
195void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone )
196{
197 Ivy_Obj_t * pTemp;
198 int i;
199 assert( !Ivy_IsComplement(pObj) );
200 assert( Ivy_ObjIsNode(pObj) );
201 // mark the nodes
202 Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pTemp, i )
203 Ivy_Regular(pTemp)->fMarkA = 1;
204 assert( pObj->fMarkA == 0 );
205 // collect the cone
206 Vec_PtrClear( vCone );
207 Ivy_ManCollectCone_rec( pObj, vCone );
208 // unmark the nodes
209 Vec_PtrForEachEntry( Ivy_Obj_t *, vFront, pTemp, i )
210 Ivy_Regular(pTemp)->fMarkA = 0;
211}
212
225{
226 Vec_Vec_t * vNodes;
227 Ivy_Obj_t * pObj;
228 int i;
229 vNodes = Vec_VecAlloc( 100 );
230 Ivy_ManForEachObj( p, pObj, i )
231 {
232 assert( !Ivy_ObjIsBuf(pObj) );
233 if ( Ivy_ObjIsNode(pObj) )
234 Vec_VecPush( vNodes, pObj->Level, pObj );
235 }
236 return vNodes;
237}
238
251{
252 Ivy_Obj_t * pObj;
253 Vec_Int_t * vLevelsR;
254 Vec_Vec_t * vNodes;
255 int i, k, Level, LevelMax;
256 assert( p->vRequired == NULL );
257 // start the required times
258 vLevelsR = Vec_IntStart( Ivy_ManObjIdMax(p) + 1 );
259 // iterate through the nodes in the reverse order
260 vNodes = Ivy_ManLevelize( p );
261 Vec_VecForEachEntryReverseReverse( Ivy_Obj_t *, vNodes, pObj, i, k )
262 {
263 Level = Vec_IntEntry( vLevelsR, pObj->Id ) + 1 + Ivy_ObjIsExor(pObj);
264 if ( Vec_IntEntry( vLevelsR, Ivy_ObjFaninId0(pObj) ) < Level )
265 Vec_IntWriteEntry( vLevelsR, Ivy_ObjFaninId0(pObj), Level );
266 if ( Vec_IntEntry( vLevelsR, Ivy_ObjFaninId1(pObj) ) < Level )
267 Vec_IntWriteEntry( vLevelsR, Ivy_ObjFaninId1(pObj), Level );
268 }
269 Vec_VecFree( vNodes );
270 // convert it into the required times
271 LevelMax = Ivy_ManLevels( p );
272//printf( "max %5d\n",LevelMax );
273 Ivy_ManForEachObj( p, pObj, i )
274 {
275 Level = Vec_IntEntry( vLevelsR, pObj->Id );
276 Vec_IntWriteEntry( vLevelsR, pObj->Id, LevelMax - Level );
277//printf( "%5d : %5d %5d\n", pObj->Id, Level, LevelMax - Level );
278 }
279 p->vRequired = vLevelsR;
280 return vLevelsR;
281}
282
295{
296 // skip the node if it is already visited
297 if ( Ivy_ObjIsTravIdPrevious(p, pObj) )
298 return 1;
299 // check if the node is part of the combinational loop
300 if ( Ivy_ObjIsTravIdCurrent(p, pObj) )
301 {
302 fprintf( stdout, "Manager contains combinational loop!\n" );
303 fprintf( stdout, "Node \"%d\" is encountered twice on the following path:\n", Ivy_ObjId(pObj) );
304 fprintf( stdout, " %d", Ivy_ObjId(pObj) );
305 return 0;
306 }
307 // mark this node as a node on the current path
308 Ivy_ObjSetTravIdCurrent( p, pObj );
309 // explore equivalent nodes if pObj is the main node
310 if ( p->pHaig == NULL && pObj->pEquiv && Ivy_ObjRefs(pObj) > 0 )
311 {
312 Ivy_Obj_t * pTemp;
313 assert( !Ivy_IsComplement(pObj->pEquiv) );
314 for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) )
315 {
316 // traverse the fanin's cone searching for the loop
317 if ( !Ivy_ManIsAcyclic_rec(p, pTemp) )
318 {
319 // return as soon as the loop is detected
320 fprintf( stdout, " -> (%d", Ivy_ObjId(pObj) );
321 for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) )
322 fprintf( stdout, " %d", Ivy_ObjId(pTemp) );
323 fprintf( stdout, ")" );
324 return 0;
325 }
326 }
327 }
328 // quite if it is a CI node
329 if ( Ivy_ObjIsCi(pObj) || Ivy_ObjIsConst1(pObj) )
330 {
331 // mark this node as a visited node
332 Ivy_ObjSetTravIdPrevious( p, pObj );
333 return 1;
334 }
335 assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) );
336 // traverse the fanin's cone searching for the loop
337 if ( !Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin0(pObj)) )
338 {
339 // return as soon as the loop is detected
340 fprintf( stdout, " -> %d", Ivy_ObjId(pObj) );
341 return 0;
342 }
343 // traverse the fanin's cone searching for the loop
344 if ( Ivy_ObjIsNode(pObj) && !Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin1(pObj)) )
345 {
346 // return as soon as the loop is detected
347 fprintf( stdout, " -> %d", Ivy_ObjId(pObj) );
348 return 0;
349 }
350 // mark this node as a visited node
351 Ivy_ObjSetTravIdPrevious( p, pObj );
352 return 1;
353}
354
374{
375 Ivy_Obj_t * pObj;
376 int fAcyclic, i;
377 // set the traversal ID for this DFS ordering
380 // pObj->TravId == pNet->nTravIds means "pObj is on the path"
381 // pObj->TravId == pNet->nTravIds - 1 means "pObj is visited but is not on the path"
382 // pObj->TravId < pNet->nTravIds - 1 means "pObj is not visited"
383 // traverse the network to detect cycles
384 fAcyclic = 1;
385 Ivy_ManForEachCo( p, pObj, i )
386 {
387 // traverse the output logic cone
388 if ( (fAcyclic = Ivy_ManIsAcyclic_rec(p, Ivy_ObjFanin0(pObj))) )
389 continue;
390 // stop as soon as the first loop is detected
391 fprintf( stdout, " (cone of %s \"%d\")\n", Ivy_ObjIsLatch(pObj)? "latch" : "PO", Ivy_ObjId(pObj) );
392 break;
393 }
394 return fAcyclic;
395}
396
408int Ivy_ManSetLevels_rec( Ivy_Obj_t * pObj, int fHaig )
409{
410 // quit if the node is visited
411 if ( Ivy_ObjIsMarkA(pObj) )
412 return pObj->Level;
413 Ivy_ObjSetMarkA(pObj);
414 // quit if this is a CI
415 if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsCi(pObj) )
416 return 0;
417 assert( Ivy_ObjIsBuf(pObj) || Ivy_ObjIsAnd(pObj) || Ivy_ObjIsExor(pObj) );
418 // get levels of the fanins
419 Ivy_ManSetLevels_rec( Ivy_ObjFanin0(pObj), fHaig );
420 if ( !Ivy_ObjIsBuf(pObj) )
421 Ivy_ManSetLevels_rec( Ivy_ObjFanin1(pObj), fHaig );
422 // get level of the node
423 if ( Ivy_ObjIsBuf(pObj) )
424 pObj->Level = 1 + Ivy_ObjFanin0(pObj)->Level;
425 else if ( Ivy_ObjIsNode(pObj) )
426 pObj->Level = Ivy_ObjLevelNew( pObj );
427 else assert( 0 );
428 // get level of other choices
429 if ( fHaig && pObj->pEquiv && Ivy_ObjRefs(pObj) > 0 )
430 {
431 Ivy_Obj_t * pTemp;
432 unsigned LevelMax = pObj->Level;
433 for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) )
434 {
435 Ivy_ManSetLevels_rec( pTemp, fHaig );
436 LevelMax = IVY_MAX( LevelMax, pTemp->Level );
437 }
438 // get this level
439 pObj->Level = LevelMax;
440 for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) )
441 pTemp->Level = LevelMax;
442 }
443 return pObj->Level;
444}
445
457int Ivy_ManSetLevels( Ivy_Man_t * p, int fHaig )
458{
459 Ivy_Obj_t * pObj;
460 int i, LevelMax;
461 // check if CIs have choices
462 if ( fHaig )
463 {
464 Ivy_ManForEachCi( p, pObj, i )
465 if ( pObj->pEquiv )
466 printf( "CI %d has a choice, which will not be visualized.\n", pObj->Id );
467 }
468 // clean the levels
469 Ivy_ManForEachObj( p, pObj, i )
470 pObj->Level = 0;
471 // compute the levels
472 LevelMax = 0;
473 Ivy_ManForEachCo( p, pObj, i )
474 {
475 Ivy_ManSetLevels_rec( Ivy_ObjFanin0(pObj), fHaig );
476 LevelMax = IVY_MAX( LevelMax, (int)Ivy_ObjFanin0(pObj)->Level );
477 }
478 // compute levels of nodes without fanout
479 Ivy_ManForEachObj( p, pObj, i )
480 if ( (Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj)) && Ivy_ObjRefs(pObj) == 0 )
481 {
482 Ivy_ManSetLevels_rec( pObj, fHaig );
483 LevelMax = IVY_MAX( LevelMax, (int)pObj->Level );
484 }
485 // clean the marks
486 Ivy_ManForEachObj( p, pObj, i )
487 Ivy_ObjClearMarkA(pObj);
488 return LevelMax;
489}
490
491
495
496
498
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
Cube * p
Definition exorList.c:222
Vec_Int_t * Ivy_ManRequiredLevels(Ivy_Man_t *p)
Definition ivyDfs.c:250
int Ivy_ManIsAcyclic_rec(Ivy_Man_t *p, Ivy_Obj_t *pObj)
Definition ivyDfs.c:294
void Ivy_ManCollectCone_rec(Ivy_Obj_t *pObj, Vec_Ptr_t *vCone)
Definition ivyDfs.c:168
int Ivy_ManSetLevels_rec(Ivy_Obj_t *pObj, int fHaig)
Definition ivyDfs.c:408
int Ivy_ManIsAcyclic(Ivy_Man_t *p)
Definition ivyDfs.c:373
Vec_Int_t * Ivy_ManDfsSeq(Ivy_Man_t *p, Vec_Int_t **pvLatches)
Definition ivyDfs.c:121
ABC_NAMESPACE_IMPL_START void Ivy_ManDfs_rec(Ivy_Man_t *p, Ivy_Obj_t *pObj, Vec_Int_t *vNodes)
DECLARATIONS ///.
Definition ivyDfs.c:45
Vec_Int_t * Ivy_ManDfs(Ivy_Man_t *p)
Definition ivyDfs.c:87
Vec_Vec_t * Ivy_ManLevelize(Ivy_Man_t *p)
Definition ivyDfs.c:224
int Ivy_ManSetLevels(Ivy_Man_t *p, int fHaig)
Definition ivyDfs.c:457
void Ivy_ManCollectCone(Ivy_Obj_t *pObj, Vec_Ptr_t *vFront, Vec_Ptr_t *vCone)
Definition ivyDfs.c:195
#define Ivy_ManForEachCo(p, pObj, i)
Definition ivy.h:399
typedefABC_NAMESPACE_HEADER_START struct Ivy_Man_t_ Ivy_Man_t
INCLUDES ///.
Definition ivy.h:46
void Ivy_ManIncrementTravId(Ivy_Man_t *p)
DECLARATIONS ///.
Definition ivyUtil.c:45
#define IVY_MAX(a, b)
Definition ivy.h:183
#define Ivy_ManForEachLatch(p, pObj, i)
Definition ivy.h:405
#define Ivy_ManForEachObj(p, pObj, i)
Definition ivy.h:393
#define Ivy_ManForEachPo(p, pObj, i)
Definition ivy.h:390
struct Ivy_Obj_t_ Ivy_Obj_t
Definition ivy.h:47
#define Ivy_ManForEachCi(p, pObj, i)
Definition ivy.h:396
#define Ivy_ManForEachNodeVec(p, vIds, pObj, i)
Definition ivy.h:408
int Ivy_ManLevels(Ivy_Man_t *p)
Definition ivyUtil.c:249
unsigned fMarkB
Definition ivy.h:79
Ivy_Obj_t * pEquiv
Definition ivy.h:93
int Id
Definition ivy.h:75
unsigned Level
Definition ivy.h:84
unsigned fMarkA
Definition ivy.h:78
#define assert(ex)
Definition util_old.h:213
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
#define Vec_VecForEachEntryReverseReverse(Type, vGlob, pEntry, i, k)
Definition vecVec.h:101
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition vecVec.h:42