ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ivyHaig.c
Go to the documentation of this file.
1
20
21#include "ivy.h"
22
24
25
29
30/*
31 HAIGing rules in working AIG:
32 - Each node in the working AIG has a pointer to the corresponding node in HAIG
33 (this node is not necessarily the representative of the equivalence class of HAIG nodes)
34 - This pointer is complemented if the AIG node and its corresponding HAIG node have different phase
35
36 Choice node rules in HAIG:
37 - Equivalent nodes are linked into a ring
38 - Exactly one node in the ring has fanouts (this node is called the representative)
39 - The pointer going from a node to the next node in the ring is complemented
40 if the first node is complemented, compared to the representative node of the equivalence class
41 - (consequence of the above) The representative node always has non-complemented pointer to the next node
42 - New nodes are inserted into the ring immediately after the representative node
43*/
44
45// returns the representative node of the given HAIG node
46static inline Ivy_Obj_t * Ivy_HaigObjRepr( Ivy_Obj_t * pObj )
47{
48 Ivy_Obj_t * pTemp;
49 assert( !Ivy_IsComplement(pObj) );
50 // if the node has no equivalent node or has fanout, it is representative
51 if ( pObj->pEquiv == NULL || Ivy_ObjRefs(pObj) > 0 )
52 return pObj;
53 // the node belongs to a class and is not a representative
54 // complemented edge (pObj->pEquiv) tells if it is complemented w.r.t. the repr
55 for ( pTemp = Ivy_Regular(pObj->pEquiv); pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) )
56 if ( Ivy_ObjRefs(pTemp) > 0 )
57 break;
58 // return the representative node
59 assert( Ivy_ObjRefs(pTemp) > 0 );
60 return Ivy_NotCond( pTemp, Ivy_IsComplement(pObj->pEquiv) );
61}
62
63// counts the number of nodes in the equivalence class
64static inline int Ivy_HaigObjCountClass( Ivy_Obj_t * pObj )
65{
66 Ivy_Obj_t * pTemp;
67 int Counter;
68 assert( !Ivy_IsComplement(pObj) );
69 assert( Ivy_ObjRefs(pObj) > 0 );
70 if ( pObj->pEquiv == NULL )
71 return 1;
72 assert( !Ivy_IsComplement(pObj->pEquiv) );
73 Counter = 1;
74 for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) )
75 Counter++;
76 return Counter;
77}
78
82
94void Ivy_ManHaigStart( Ivy_Man_t * p, int fVerbose )
95{
96 Vec_Int_t * vLatches;
97 Ivy_Obj_t * pObj;
98 int i;
99 assert( p->pHaig == NULL );
100 p->pHaig = Ivy_ManDup( p );
101
102 if ( fVerbose )
103 {
104 printf( "Starting : " );
105 Ivy_ManPrintStats( p->pHaig );
106 }
107
108 // collect latches of design D and set their values to be DC
109 vLatches = Vec_IntAlloc( 100 );
110 Ivy_ManForEachLatch( p->pHaig, pObj, i )
111 {
112 pObj->Init = IVY_INIT_DC;
113 Vec_IntPush( vLatches, pObj->Id );
114 }
115 p->pHaig->pData = vLatches;
116/*
117 {
118 int x;
119 Ivy_ManShow( p, 0, NULL );
120 Ivy_ManShow( p->pHaig, 1, NULL );
121 x = 0;
122 }
123*/
124}
125
138{
139 Ivy_Obj_t * pObj;
140 int i;
141 assert( p->pHaig != NULL );
142 Ivy_ManConst1(pNew)->pEquiv = Ivy_ManConst1(p)->pEquiv;
143 Ivy_ManForEachPi( pNew, pObj, i )
144 pObj->pEquiv = Ivy_ManPi( p, i )->pEquiv;
145 pNew->pHaig = p->pHaig;
146}
147
160{
161 Ivy_Obj_t * pObj;
162 int i;
163 assert( p->pHaig != NULL );
164 Vec_IntFree( (Vec_Int_t *)p->pHaig->pData );
165 Ivy_ManStop( p->pHaig );
166 p->pHaig = NULL;
167 // remove dangling pointers to the HAIG objects
168 Ivy_ManForEachObj( p, pObj, i )
169 pObj->pEquiv = NULL;
170}
171
184{
185 Ivy_Obj_t * pEquiv0, * pEquiv1;
186 assert( p->pHaig != NULL );
187 assert( !Ivy_IsComplement(pObj) );
188 if ( Ivy_ObjType(pObj) == IVY_BUF )
189 pObj->pEquiv = Ivy_ObjChild0Equiv(pObj);
190 else if ( Ivy_ObjType(pObj) == IVY_LATCH )
191 {
192// pObj->pEquiv = Ivy_Latch( p->pHaig, Ivy_ObjChild0Equiv(pObj), pObj->Init );
193 pEquiv0 = Ivy_ObjChild0Equiv(pObj);
194 pEquiv0 = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pEquiv0)), Ivy_IsComplement(pEquiv0) );
195 pObj->pEquiv = Ivy_Latch( p->pHaig, pEquiv0, (Ivy_Init_t)pObj->Init );
196 }
197 else if ( Ivy_ObjType(pObj) == IVY_AND )
198 {
199// pObj->pEquiv = Ivy_And( p->pHaig, Ivy_ObjChild0Equiv(pObj), Ivy_ObjChild1Equiv(pObj) );
200 pEquiv0 = Ivy_ObjChild0Equiv(pObj);
201 pEquiv0 = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pEquiv0)), Ivy_IsComplement(pEquiv0) );
202 pEquiv1 = Ivy_ObjChild1Equiv(pObj);
203 pEquiv1 = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pEquiv1)), Ivy_IsComplement(pEquiv1) );
204 pObj->pEquiv = Ivy_And( p->pHaig, pEquiv0, pEquiv1 );
205 }
206 else assert( 0 );
207 // make sure the node points to the representative
208// pObj->pEquiv = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pObj->pEquiv)), Ivy_IsComplement(pObj->pEquiv) );
209}
210
222int Ivy_ObjIsInTfi_rec( Ivy_Obj_t * pObjNew, Ivy_Obj_t * pObjOld, int Levels )
223{
224 if ( pObjNew == pObjOld )
225 return 1;
226 if ( Levels == 0 || Ivy_ObjIsCi(pObjNew) || Ivy_ObjIsConst1(pObjNew) )
227 return 0;
228 if ( Ivy_ObjIsInTfi_rec( Ivy_ObjFanin0(pObjNew), pObjOld, Levels - 1 ) )
229 return 1;
230 if ( Ivy_ObjIsNode(pObjNew) && Ivy_ObjIsInTfi_rec( Ivy_ObjFanin1(pObjNew), pObjOld, Levels - 1 ) )
231 return 1;
232 return 0;
233}
234
247{
248 Ivy_Obj_t * pObjOldHaig, * pObjNewHaig;
249 Ivy_Obj_t * pObjOldHaigR, * pObjNewHaigR;
250 int fCompl;
251//printf( "\nCreating choice for %d and %d in AIG\n", pObjOld->Id, Ivy_Regular(pObjNew)->Id );
252
253 assert( p->pHaig != NULL );
254 assert( !Ivy_IsComplement(pObjOld) );
255 // get pointers to the representatives of pObjOld and pObjNew
256 pObjOldHaig = pObjOld->pEquiv;
257 pObjNewHaig = Ivy_NotCond( Ivy_Regular(pObjNew)->pEquiv, Ivy_IsComplement(pObjNew) );
258 // get the classes
259 pObjOldHaig = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pObjOldHaig)), Ivy_IsComplement(pObjOldHaig) );
260 pObjNewHaig = Ivy_NotCond( Ivy_HaigObjRepr(Ivy_Regular(pObjNewHaig)), Ivy_IsComplement(pObjNewHaig) );
261 // get regular pointers
262 pObjOldHaigR = Ivy_Regular(pObjOldHaig);
263 pObjNewHaigR = Ivy_Regular(pObjNewHaig);
264 // check if there is phase difference between them
265 fCompl = (Ivy_IsComplement(pObjOldHaig) != Ivy_IsComplement(pObjNewHaig));
266 // if the class is the same, nothing to do
267 if ( pObjOldHaigR == pObjNewHaigR )
268 return;
269 // if the second node belongs to a class, do not merge classes (for the time being)
270 if ( Ivy_ObjRefs(pObjOldHaigR) == 0 || pObjNewHaigR->pEquiv != NULL ||
271 Ivy_ObjRefs(pObjNewHaigR) > 0 ) //|| Ivy_ObjIsInTfi_rec(pObjNewHaigR, pObjOldHaigR, 10) )
272 {
273/*
274 if ( pObjNewHaigR->pEquiv != NULL )
275 printf( "c" );
276 if ( Ivy_ObjRefs(pObjNewHaigR) > 0 )
277 printf( "f" );
278 printf( " " );
279*/
280 p->pHaig->nClassesSkip++;
281 return;
282 }
283
284 // add this node to the class of pObjOldHaig
285 assert( Ivy_ObjRefs(pObjOldHaigR) > 0 );
286 assert( !Ivy_IsComplement(pObjOldHaigR->pEquiv) );
287 if ( pObjOldHaigR->pEquiv == NULL )
288 pObjNewHaigR->pEquiv = Ivy_NotCond( pObjOldHaigR, fCompl );
289 else
290 pObjNewHaigR->pEquiv = Ivy_NotCond( pObjOldHaigR->pEquiv, fCompl );
291 pObjOldHaigR->pEquiv = pObjNewHaigR;
292//printf( "Setting choice node %d -> %d.\n", pObjOldHaigR->Id, pObjNewHaigR->Id );
293 // update the class of the new node
294// Ivy_Regular(pObjNew)->pEquiv = Ivy_NotCond( pObjOldHaigR, fCompl ^ Ivy_IsComplement(pObjNew) );
295//printf( "Creating choice for %d and %d in HAIG\n", pObjOldHaigR->Id, pObjNewHaigR->Id );
296
297// if ( pObjOldHaigR->Id == 13 )
298// {
299// Ivy_ManShow( p, 0 );
300// Ivy_ManShow( p->pHaig, 1 );
301// }
302// if ( !Ivy_ManIsAcyclic( p->pHaig ) )
303// printf( "HAIG contains a cycle\n" );
304}
305
317int Ivy_ManHaigCountChoices( Ivy_Man_t * p, int * pnChoices )
318{
319 Ivy_Obj_t * pObj;
320 int nChoices, nChoiceNodes, Counter, i;
321 assert( p->pHaig != NULL );
322 nChoices = nChoiceNodes = 0;
323 Ivy_ManForEachObj( p->pHaig, pObj, i )
324 {
325 if ( Ivy_ObjIsTerm(pObj) || i == 0 )
326 continue;
327 if ( Ivy_ObjRefs(pObj) == 0 )
328 continue;
329 Counter = Ivy_HaigObjCountClass( pObj );
330 nChoiceNodes += (int)(Counter > 1);
331 nChoices += Counter - 1;
332// if ( Counter > 1 )
333// printf( "Choice node %d %s\n", pObj->Id, Ivy_ObjIsLatch(pObj)? "(latch)": "" );
334 }
335 *pnChoices = nChoices;
336 return nChoiceNodes;
337}
338
350void Ivy_ManHaigPostprocess( Ivy_Man_t * p, int fVerbose )
351{
352 int nChoices, nChoiceNodes;
353
354 assert( p->pHaig != NULL );
355
356 if ( fVerbose )
357 {
358 printf( "Final : " );
360 printf( "HAIG : " );
361 Ivy_ManPrintStats( p->pHaig );
362
363 // print choice node stats
364 nChoiceNodes = Ivy_ManHaigCountChoices( p, &nChoices );
365 printf( "Total choice nodes = %d. Total choices = %d. Skipped classes = %d.\n",
366 nChoiceNodes, nChoices, p->pHaig->nClassesSkip );
367 }
368
369 if ( Ivy_ManIsAcyclic( p->pHaig ) )
370 {
371 if ( fVerbose )
372 printf( "HAIG is acyclic\n" );
373 }
374 else
375 printf( "HAIG contains a cycle\n" );
376
377// if ( fVerbose )
378// Ivy_ManHaigSimulate( p );
379}
380
381
393static inline Ivy_Init_t Ivy_ManHaigSimulateAnd( Ivy_Init_t In0, Ivy_Init_t In1 )
394{
395 assert( In0 != IVY_INIT_NONE && In1 != IVY_INIT_NONE );
396 if ( In0 == IVY_INIT_DC || In1 == IVY_INIT_DC )
397 return IVY_INIT_DC;
398 if ( In0 == IVY_INIT_1 && In1 == IVY_INIT_1 )
399 return IVY_INIT_1;
400 return IVY_INIT_0;
401}
402
414static inline Ivy_Init_t Ivy_ManHaigSimulateChoice( Ivy_Init_t In0, Ivy_Init_t In1 )
415{
416 assert( In0 != IVY_INIT_NONE && In1 != IVY_INIT_NONE );
417 if ( (In0 == IVY_INIT_0 && In1 == IVY_INIT_1) || (In0 == IVY_INIT_1 && In1 == IVY_INIT_0) )
418 {
419 printf( "Compatibility fails.\n" );
420 return IVY_INIT_0;
421 }
422 if ( In0 == IVY_INIT_DC && In1 == IVY_INIT_DC )
423 return IVY_INIT_DC;
424 if ( In0 != IVY_INIT_DC )
425 return In0;
426 return In1;
427}
428
441{
442 Vec_Int_t * vNodes, * vLatches, * vLatchesD;
443 Ivy_Obj_t * pObj, * pTemp;
444 Ivy_Init_t In0, In1;
445 int i, k, Counter;
446 int fVerbose = 0;
447
448 // check choices
450
451 // switch to HAIG
452 assert( p->pHaig != NULL );
453 p = p->pHaig;
454
455if ( fVerbose )
456Ivy_ManForEachPi( p, pObj, i )
457printf( "Setting PI %d\n", pObj->Id );
458
459 // collect latches and nodes in the DFS order
460 vNodes = Ivy_ManDfsSeq( p, &vLatches );
461
462if ( fVerbose )
463Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
464printf( "Collected node %d with fanins %d and %d\n", pObj->Id, Ivy_ObjFanin0(pObj)->Id, Ivy_ObjFanin1(pObj)->Id );
465
466 // set the PI values
467 Ivy_ManConst1(p)->Init = IVY_INIT_1;
468 Ivy_ManForEachPi( p, pObj, i )
469 pObj->Init = IVY_INIT_0;
470
471 // set the latch values
472 Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
473 pObj->Init = IVY_INIT_DC;
474 // set the latches of D to be determinate
475 vLatchesD = (Vec_Int_t *)p->pData;
476 Ivy_ManForEachNodeVec( p, vLatchesD, pObj, i )
477 pObj->Init = IVY_INIT_0;
478
479 // perform several rounds of simulation
480 for ( k = 0; k < 10; k++ )
481 {
482 // count the number of non-determinate values
483 Counter = 0;
484 Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
485 Counter += ( pObj->Init == IVY_INIT_DC );
486 printf( "Iter %d : Non-determinate = %d\n", k, Counter );
487
488 // simulate the internal nodes
489 Ivy_ManForEachNodeVec( p, vNodes, pObj, i )
490 {
491if ( fVerbose )
492printf( "Processing node %d with fanins %d and %d\n", pObj->Id, Ivy_ObjFanin0(pObj)->Id, Ivy_ObjFanin1(pObj)->Id );
493 In0 = Ivy_InitNotCond( (Ivy_Init_t)Ivy_ObjFanin0(pObj)->Init, Ivy_ObjFaninC0(pObj) );
494 In1 = Ivy_InitNotCond( (Ivy_Init_t)Ivy_ObjFanin1(pObj)->Init, Ivy_ObjFaninC1(pObj) );
495 pObj->Init = Ivy_ManHaigSimulateAnd( In0, In1 );
496 // simulate the equivalence class if the node is a representative
497 if ( pObj->pEquiv && Ivy_ObjRefs(pObj) > 0 )
498 {
499if ( fVerbose )
500printf( "Processing choice node %d\n", pObj->Id );
501 In0 = (Ivy_Init_t)pObj->Init;
502 assert( !Ivy_IsComplement(pObj->pEquiv) );
503 for ( pTemp = pObj->pEquiv; pTemp != pObj; pTemp = Ivy_Regular(pTemp->pEquiv) )
504 {
505if ( fVerbose )
506printf( "Processing secondary node %d\n", pTemp->Id );
507 In1 = Ivy_InitNotCond( (Ivy_Init_t)pTemp->Init, Ivy_IsComplement(pTemp->pEquiv) );
508 In0 = Ivy_ManHaigSimulateChoice( In0, In1 );
509 }
510 pObj->Init = In0;
511 }
512 }
513
514 // simulate the latches
515 Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
516 {
517 pObj->Level = Ivy_ObjFanin0(pObj)->Init;
518if ( fVerbose )
519printf( "Using latch %d with fanin %d\n", pObj->Id, Ivy_ObjFanin0(pObj)->Id );
520 }
521 Ivy_ManForEachNodeVec( p, vLatches, pObj, i )
522 pObj->Init = pObj->Level, pObj->Level = 0;
523 }
524 // free arrays
525 Vec_IntFree( vNodes );
526 Vec_IntFree( vLatches );
527}
528
532
533
535
#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
int Ivy_ObjIsInTfi_rec(Ivy_Obj_t *pObjNew, Ivy_Obj_t *pObjOld, int Levels)
Definition ivyHaig.c:222
void Ivy_ManHaigSimulate(Ivy_Man_t *p)
Definition ivyHaig.c:440
void Ivy_ManHaigTrasfer(Ivy_Man_t *p, Ivy_Man_t *pNew)
Definition ivyHaig.c:137
int Ivy_ManHaigCountChoices(Ivy_Man_t *p, int *pnChoices)
Definition ivyHaig.c:317
void Ivy_ManHaigStop(Ivy_Man_t *p)
Definition ivyHaig.c:159
void Ivy_ManHaigStart(Ivy_Man_t *p, int fVerbose)
FUNCTION DEFINITIONS ///.
Definition ivyHaig.c:94
void Ivy_ManHaigCreateChoice(Ivy_Man_t *p, Ivy_Obj_t *pObjOld, Ivy_Obj_t *pObjNew)
Definition ivyHaig.c:246
void Ivy_ManHaigCreateObj(Ivy_Man_t *p, Ivy_Obj_t *pObj)
Definition ivyHaig.c:183
void Ivy_ManHaigPostprocess(Ivy_Man_t *p, int fVerbose)
Definition ivyHaig.c:350
typedefABC_NAMESPACE_HEADER_START struct Ivy_Man_t_ Ivy_Man_t
INCLUDES ///.
Definition ivy.h:46
Ivy_Init_t
Definition ivy.h:65
@ IVY_INIT_0
Definition ivy.h:67
@ IVY_INIT_1
Definition ivy.h:68
@ IVY_INIT_DC
Definition ivy.h:69
@ IVY_INIT_NONE
Definition ivy.h:66
Ivy_Obj_t * Ivy_Latch(Ivy_Man_t *p, Ivy_Obj_t *pObj, Ivy_Init_t Init)
Definition ivyOper.c:287
#define Ivy_ManForEachLatch(p, pObj, i)
Definition ivy.h:405
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
#define Ivy_ManForEachObj(p, pObj, i)
Definition ivy.h:393
void Ivy_ManStop(Ivy_Man_t *p)
Definition ivyMan.c:238
struct Ivy_Obj_t_ Ivy_Obj_t
Definition ivy.h:47
void Ivy_ManPrintStats(Ivy_Man_t *p)
Definition ivyMan.c:456
#define Ivy_ManForEachNodeVec(p, vIds, pObj, i)
Definition ivy.h:408
@ IVY_AND
Definition ivy.h:58
@ IVY_LATCH
Definition ivy.h:57
@ IVY_BUF
Definition ivy.h:60
#define Ivy_ManForEachPi(p, pObj, i)
ITERATORS ///.
Definition ivy.h:387
Ivy_Man_t * Ivy_ManDup(Ivy_Man_t *p)
Definition ivyMan.c:110
int Ivy_ManCheckChoices(Ivy_Man_t *p)
Definition ivyCheck.c:255
Ivy_Obj_t * Ivy_And(Ivy_Man_t *p, Ivy_Obj_t *p0, Ivy_Obj_t *p1)
Definition ivyOper.c:84
Ivy_Obj_t * pEquiv
Definition ivy.h:93
int Id
Definition ivy.h:75
unsigned Level
Definition ivy.h:84
unsigned Init
Definition ivy.h:83
#define assert(ex)
Definition util_old.h:213