ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ivyDfs.c File Reference
#include "ivy.h"
Include dependency graph for ivyDfs.c:

Go to the source code of this file.

Functions

ABC_NAMESPACE_IMPL_START void Ivy_ManDfs_rec (Ivy_Man_t *p, Ivy_Obj_t *pObj, Vec_Int_t *vNodes)
 DECLARATIONS ///.
 
Vec_Int_tIvy_ManDfs (Ivy_Man_t *p)
 
Vec_Int_tIvy_ManDfsSeq (Ivy_Man_t *p, Vec_Int_t **pvLatches)
 
void Ivy_ManCollectCone_rec (Ivy_Obj_t *pObj, Vec_Ptr_t *vCone)
 
void Ivy_ManCollectCone (Ivy_Obj_t *pObj, Vec_Ptr_t *vFront, Vec_Ptr_t *vCone)
 
Vec_Vec_tIvy_ManLevelize (Ivy_Man_t *p)
 
Vec_Int_tIvy_ManRequiredLevels (Ivy_Man_t *p)
 
int Ivy_ManIsAcyclic_rec (Ivy_Man_t *p, Ivy_Obj_t *pObj)
 
int Ivy_ManIsAcyclic (Ivy_Man_t *p)
 
int Ivy_ManSetLevels_rec (Ivy_Obj_t *pObj, int fHaig)
 
int Ivy_ManSetLevels (Ivy_Man_t *p, int fHaig)
 

Function Documentation

◆ Ivy_ManCollectCone()

void Ivy_ManCollectCone ( Ivy_Obj_t * pObj,
Vec_Ptr_t * vFront,
Vec_Ptr_t * vCone )

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

Synopsis [Collects nodes in the cone.]

Description []

SideEffects []

SeeAlso []

Definition at line 195 of file ivyDfs.c.

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}
void Ivy_ManCollectCone_rec(Ivy_Obj_t *pObj, Vec_Ptr_t *vCone)
Definition ivyDfs.c:168
struct Ivy_Obj_t_ Ivy_Obj_t
Definition ivy.h:47
unsigned fMarkA
Definition ivy.h:78
#define assert(ex)
Definition util_old.h:213
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
Here is the call graph for this function:

◆ Ivy_ManCollectCone_rec()

void Ivy_ManCollectCone_rec ( Ivy_Obj_t * pObj,
Vec_Ptr_t * vCone )

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

Synopsis [Collects nodes in the cone.]

Description []

SideEffects []

SeeAlso []

Definition at line 168 of file ivyDfs.c.

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}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Ivy_ManDfs()

Vec_Int_t * Ivy_ManDfs ( Ivy_Man_t * p)

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

Synopsis [Collects AND/EXOR nodes in the DFS order from CIs to COs.]

Description []

SideEffects []

SeeAlso []

Definition at line 87 of file ivyDfs.c.

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}
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
Cube * p
Definition exorList.c:222
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
#define Ivy_ManForEachObj(p, pObj, i)
Definition ivy.h:393
#define Ivy_ManForEachPo(p, pObj, i)
Definition ivy.h:390
unsigned fMarkB
Definition ivy.h:79
Here is the call graph for this function:

◆ Ivy_ManDfs_rec()

ABC_NAMESPACE_IMPL_START void Ivy_ManDfs_rec ( Ivy_Man_t * p,
Ivy_Obj_t * pObj,
Vec_Int_t * vNodes )

DECLARATIONS ///.

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

FileName [ivyDfs.c]

SystemName [ABC: Logic synthesis and verification system.]

PackageName [And-Inverter Graph package.]

Synopsis [DFS collection procedures.]

Author [Alan Mishchenko]

Affiliation [UC Berkeley]

Date [Ver. 1.0. Started - May 11, 2006.]

Revision [

Id
ivyDfs.c,v 1.00 2006/05/11 00:00:00 alanmi Exp

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

Synopsis [Collects nodes in the DFS order.]

Description []

SideEffects []

SeeAlso []

Definition at line 45 of file ivyDfs.c.

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}
Ivy_Obj_t * pEquiv
Definition ivy.h:93
int Id
Definition ivy.h:75
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Ivy_ManDfsSeq()

Vec_Int_t * Ivy_ManDfsSeq ( Ivy_Man_t * p,
Vec_Int_t ** pvLatches )

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

Synopsis [Collects AND/EXOR nodes in the DFS order from CIs to COs.]

Description []

SideEffects []

SeeAlso []

Definition at line 121 of file ivyDfs.c.

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}
#define Ivy_ManForEachLatch(p, pObj, i)
Definition ivy.h:405
#define Ivy_ManForEachNodeVec(p, vIds, pObj, i)
Definition ivy.h:408
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Ivy_ManIsAcyclic()

int Ivy_ManIsAcyclic ( Ivy_Man_t * p)

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

Synopsis [Detects combinational loops.]

Description [This procedure is based on the idea suggested by Donald Chai. As we traverse the network and visit the nodes, we need to distinquish three types of nodes: (1) those that are visited for the first time, (2) those that have been visited in this traversal but are currently not on the traversal path, (3) those that have been visited and are currently on the travesal path. When the node of type (3) is encountered, it means that there is a combinational loop. To mark the three types of nodes, two new values of the traversal IDs are used.]

SideEffects []

SeeAlso []

Definition at line 373 of file ivyDfs.c.

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}
int Ivy_ManIsAcyclic_rec(Ivy_Man_t *p, Ivy_Obj_t *pObj)
Definition ivyDfs.c:294
#define Ivy_ManForEachCo(p, pObj, i)
Definition ivy.h:399
void Ivy_ManIncrementTravId(Ivy_Man_t *p)
DECLARATIONS ///.
Definition ivyUtil.c:45
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Ivy_ManIsAcyclic_rec()

int Ivy_ManIsAcyclic_rec ( Ivy_Man_t * p,
Ivy_Obj_t * pObj )

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

Synopsis [Recursively detects combinational loops.]

Description []

SideEffects []

SeeAlso []

Definition at line 294 of file ivyDfs.c.

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}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Ivy_ManLevelize()

Vec_Vec_t * Ivy_ManLevelize ( Ivy_Man_t * p)

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

Synopsis [Returns the nodes by level.]

Description []

SideEffects []

SeeAlso []

Definition at line 224 of file ivyDfs.c.

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}
unsigned Level
Definition ivy.h:84
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition vecVec.h:42
Here is the caller graph for this function:

◆ Ivy_ManRequiredLevels()

Vec_Int_t * Ivy_ManRequiredLevels ( Ivy_Man_t * p)

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

Synopsis [Computes required levels for each node.]

Description [Assumes topological ordering of the nodes.]

SideEffects []

SeeAlso []

Definition at line 250 of file ivyDfs.c.

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}
Vec_Vec_t * Ivy_ManLevelize(Ivy_Man_t *p)
Definition ivyDfs.c:224
int Ivy_ManLevels(Ivy_Man_t *p)
Definition ivyUtil.c:249
#define Vec_VecForEachEntryReverseReverse(Type, vGlob, pEntry, i, k)
Definition vecVec.h:101
Here is the call graph for this function:
Here is the caller graph for this function:

◆ Ivy_ManSetLevels()

int Ivy_ManSetLevels ( Ivy_Man_t * p,
int fHaig )

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

Synopsis [Sets the levels of the nodes.]

Description []

SideEffects []

SeeAlso []

Definition at line 457 of file ivyDfs.c.

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}
int Ivy_ManSetLevels_rec(Ivy_Obj_t *pObj, int fHaig)
Definition ivyDfs.c:408
#define IVY_MAX(a, b)
Definition ivy.h:183
#define Ivy_ManForEachCi(p, pObj, i)
Definition ivy.h:396
Here is the call graph for this function:

◆ Ivy_ManSetLevels_rec()

int Ivy_ManSetLevels_rec ( Ivy_Obj_t * pObj,
int fHaig )

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

Synopsis [Sets the levels of the nodes.]

Description []

SideEffects []

SeeAlso []

Definition at line 408 of file ivyDfs.c.

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}
Here is the call graph for this function:
Here is the caller graph for this function: