ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
dchChoice.c
Go to the documentation of this file.
1
20
21#include "dchInt.h"
22
24
25
29
33
46{
47 int Count;
48 if ( Aig_ObjIsTravIdCurrent( p, pObj ) )
49 return 0;
50 Aig_ObjSetTravIdCurrent( p, pObj );
51 if ( Aig_ObjIsCi(pObj) )
52 return 1;
53 assert( Aig_ObjIsNode(pObj) );
54 Count = Dch_ObjCountSupp_rec( p, Aig_ObjFanin0(pObj) );
55 Count += Dch_ObjCountSupp_rec( p, Aig_ObjFanin1(pObj) );
56 return Count;
57}
59{
61 return Dch_ObjCountSupp_rec( p, pObj );
62}
63
76{
77 Aig_Obj_t * pObj, * pRepr;
78 int i, nReprs = 0;
79 Aig_ManForEachObj( pAig, pObj, i )
80 {
81 pRepr = Aig_ObjRepr( pAig, pObj );
82 if ( pRepr == NULL )
83 continue;
84 assert( pRepr->Id < pObj->Id );
85 nReprs++;
86 }
87 return nReprs;
88}
90{
91 Aig_Obj_t * pObj, * pEquiv;
92 int i, nEquivs = 0;
93 Aig_ManForEachObj( pAig, pObj, i )
94 {
95 pEquiv = Aig_ObjEquiv( pAig, pObj );
96 if ( pEquiv == NULL )
97 continue;
98 assert( pEquiv->Id < pObj->Id );
99 nEquivs++;
100 }
101 return nEquivs;
102}
103
116{
117 int RetValue;
118 if ( pObj == NULL )
119 return 0;
120 if ( Aig_ObjIsTravIdCurrent( p, pObj ) )
121 return 0;
122 if ( Aig_ObjIsCi(pObj) )
123 {
124 RetValue = !Aig_ObjIsTravIdPrevious( p, pObj );
125 Aig_ObjSetTravIdCurrent( p, pObj );
126 return RetValue;
127 }
128 assert( Aig_ObjIsNode(pObj) );
129 Aig_ObjSetTravIdCurrent( p, pObj );
130 RetValue = Dch_ObjMarkTfi_rec( p, Aig_ObjFanin0(pObj) );
131 RetValue += Dch_ObjMarkTfi_rec( p, Aig_ObjFanin1(pObj) );
132// RetValue += Dch_ObjMarkTfi_rec( p, Aig_ObjEquiv(p, pObj) );
133 return (RetValue > 0);
134}
136{
137 // mark support of the representative node (pRepr)
139 Dch_ObjMarkTfi_rec( p, pRepr );
140 // detect if the new node (pObj) depends on additional variables
142 if ( Dch_ObjMarkTfi_rec( p, pObj ) )
143 return 1;//, printf( "1" );
144 // detect if the representative node (pRepr) depends on additional variables
146 if ( Dch_ObjMarkTfi_rec( p, pRepr ) )
147 return 1;//, printf( "2" );
148 // skip the choice if this is what is happening
149 return 0;
150}
151
164{
165 int fPrintConst = 0;
166 Aig_Obj_t * pObj;
167 int i, fProb = 0;
168 int Class0 = 0, ClassCi = 0;
169 Aig_ManForEachObj( p, pObj, i )
170 {
171 if ( Aig_ObjRepr(p, pObj) == NULL )
172 continue;
173 if ( !Aig_ObjIsNode(pObj) )
174 printf( "Obj %d is not an AND but it has a repr %d.\n", i, Aig_ObjId(Aig_ObjRepr(p, pObj)) ), fProb = 1;
175 else if ( Aig_ObjRepr(p, Aig_ObjRepr(p, pObj)) )
176 printf( "Obj %d has repr %d with a repr %d.\n", i, Aig_ObjId(Aig_ObjRepr(p, pObj)), Aig_ObjId(Aig_ObjRepr(p, Aig_ObjRepr(p, pObj))) ), fProb = 1;
177 }
178 if ( !fProb )
179 printf( "Representive verification successful.\n" );
180 else
181 printf( "Representive verification FAILED.\n" );
182 if ( !fPrintConst )
183 return;
184 // count how many representatives are const0 or a CI
185 Aig_ManForEachObj( p, pObj, i )
186 {
187 if ( Aig_ObjRepr(p, pObj) == Aig_ManConst1(p) )
188 Class0++;
189 if ( Aig_ObjRepr(p, pObj) && Aig_ObjIsCi(Aig_ObjRepr(p, pObj)) )
190 ClassCi++;
191 }
192 printf( "Const0 nodes = %d. ConstCI nodes = %d.\n", Class0, ClassCi );
193}
194
206void Dch_CheckChoices( Aig_Man_t * p, int fSkipRedSupps )
207{
208 Aig_Obj_t * pObj;
209 int i, fProb = 0;
211 Aig_ManForEachNode( p, pObj, i )
212 {
213 if ( p->pEquivs[i] != NULL )
214 {
215 if ( pObj->fMarkA == 1 )
216 printf( "node %d participates in more than one choice class\n", i ), fProb = 1;
217 pObj->fMarkA = 1;
218 // check redundancy
219 if ( fSkipRedSupps && Dch_ObjCheckSuppRed( p, pObj, p->pEquivs[i]) )
220 printf( "node %d and repr %d have diff supports\n", pObj->Id, p->pEquivs[i]->Id );
221 // consider the next one
222 pObj = p->pEquivs[i];
223 if ( p->pEquivs[Aig_ObjId(pObj)] == NULL )
224 {
225 if ( pObj->fMarkA == 1 )
226 printf( "repr %d has final node %d participates in more than one choice class\n", i, pObj->Id ), fProb = 1;
227 pObj->fMarkA = 1;
228 }
229 // consider the non-head ones
230 if ( pObj->nRefs > 0 )
231 printf( "node %d belonging to choice has fanout %d\n", pObj->Id, pObj->nRefs );
232 }
233 if ( p->pReprs && p->pReprs[i] != NULL )
234 {
235 if ( pObj->nRefs > 0 )
236 printf( "node %d has representative %d and fanout count %d\n", pObj->Id, p->pReprs[i]->Id, pObj->nRefs ), fProb = 1;
237 }
238 }
240 if ( !fProb )
241 printf( "Verification of choice AIG succeeded.\n" );
242 else
243 printf( "Verification of choice AIG FAILED.\n" );
244}
245
257int Aig_ManCheckAcyclic_rec( Aig_Man_t * p, Aig_Obj_t * pNode, int fVerbose )
258{
259 Aig_Obj_t * pFanin;
260 int fAcyclic;
261 if ( Aig_ObjIsCi(pNode) || Aig_ObjIsConst1(pNode) )
262 return 1;
263 assert( Aig_ObjIsNode(pNode) );
264 // make sure the node is not visited
265 assert( !Aig_ObjIsTravIdPrevious(p, pNode) );
266 // check if the node is part of the combinational loop
267 if ( Aig_ObjIsTravIdCurrent(p, pNode) )
268 {
269 if ( fVerbose )
270 Abc_Print( 1, "Network \"%s\" contains combinational loop!\n", p->pSpec? p->pSpec : NULL );
271 if ( fVerbose )
272 Abc_Print( 1, "Node \"%d\" is encountered twice on the following path to the COs:\n", Aig_ObjId(pNode) );
273 return 0;
274 }
275 // mark this node as a node on the current path
276 Aig_ObjSetTravIdCurrent( p, pNode );
277
278 // visit the transitive fanin
279 pFanin = Aig_ObjFanin0(pNode);
280 // check if the fanin is visited
281 if ( !Aig_ObjIsTravIdPrevious(p, pFanin) )
282 {
283 // traverse the fanin's cone searching for the loop
284 if ( !(fAcyclic = Aig_ManCheckAcyclic_rec(p, pFanin, fVerbose)) )
285 {
286 // return as soon as the loop is detected
287 if ( fVerbose )
288 Abc_Print( 1, " %d ->", Aig_ObjId(pFanin) );
289 return 0;
290 }
291 }
292
293 // visit the transitive fanin
294 pFanin = Aig_ObjFanin1(pNode);
295 // check if the fanin is visited
296 if ( !Aig_ObjIsTravIdPrevious(p, pFanin) )
297 {
298 // traverse the fanin's cone searching for the loop
299 if ( !(fAcyclic = Aig_ManCheckAcyclic_rec(p, pFanin, fVerbose)) )
300 {
301 // return as soon as the loop is detected
302 if ( fVerbose )
303 Abc_Print( 1, " %d ->", Aig_ObjId(pFanin) );
304 return 0;
305 }
306 }
307
308 // visit choices
309 if ( Aig_ObjRepr(p, pNode) == NULL && Aig_ObjEquiv(p, pNode) != NULL )
310 {
311 for ( pFanin = Aig_ObjEquiv(p, pNode); pFanin; pFanin = Aig_ObjEquiv(p, pFanin) )
312 {
313 // check if the fanin is visited
314 if ( Aig_ObjIsTravIdPrevious(p, pFanin) )
315 continue;
316 // traverse the fanin's cone searching for the loop
317 if ( (fAcyclic = Aig_ManCheckAcyclic_rec(p, pFanin, fVerbose)) )
318 continue;
319 // return as soon as the loop is detected
320 if ( fVerbose )
321 Abc_Print( 1, " %d", Aig_ObjId(pFanin) );
322 if ( fVerbose )
323 Abc_Print( 1, " (choice of %d) -> ", Aig_ObjId(pNode) );
324 return 0;
325 }
326 }
327 // mark this node as a visited node
328 Aig_ObjSetTravIdPrevious( p, pNode );
329 return 1;
330}
331int Aig_ManCheckAcyclic( Aig_Man_t * p, int fVerbose )
332{
333 Aig_Obj_t * pNode;
334 int fAcyclic;
335 int i;
336 // set the traversal ID for this DFS ordering
339 // pNode->TravId == pNet->nTravIds means "pNode is on the path"
340 // pNode->TravId == pNet->nTravIds - 1 means "pNode is visited but is not on the path"
341 // pNode->TravId < pNet->nTravIds - 1 means "pNode is not visited"
342 // traverse the network to detect cycles
343 fAcyclic = 1;
344 Aig_ManForEachCo( p, pNode, i )
345 {
346 pNode = Aig_ObjFanin0(pNode);
347 if ( Aig_ObjIsTravIdPrevious(p, pNode) )
348 continue;
349 // traverse the output logic cone
350 if ( (fAcyclic = Aig_ManCheckAcyclic_rec(p, pNode, fVerbose)) )
351 continue;
352 // stop as soon as the first loop is detected
353 if ( fVerbose )
354 Abc_Print( 1, " CO %d\n", i );
355 break;
356 }
357 return fAcyclic;
358}
359
360
373{
374 // check the trivial cases
375 if ( pObj == NULL )
376 return 0;
377 if ( Aig_ObjIsCi(pObj) )
378 return 0;
379 if ( pObj->fMarkA )
380 return 1;
381 // skip the visited node
382 if ( Aig_ObjIsTravIdCurrent( p, pObj ) )
383 return 0;
384 Aig_ObjSetTravIdCurrent( p, pObj );
385 // check the children
386 if ( Dch_ObjCheckTfi_rec( p, Aig_ObjFanin0(pObj) ) )
387 return 1;
388 if ( Dch_ObjCheckTfi_rec( p, Aig_ObjFanin1(pObj) ) )
389 return 1;
390 // check equivalent nodes
391 return Dch_ObjCheckTfi_rec( p, Aig_ObjEquiv(p, pObj) );
392}
394{
395 Aig_Obj_t * pTemp;
396 int RetValue;
397 assert( !Aig_IsComplement(pObj) );
398 assert( !Aig_IsComplement(pRepr) );
399 // mark nodes of the choice node
400 for ( pTemp = pRepr; pTemp; pTemp = Aig_ObjEquiv(p, pTemp) )
401 pTemp->fMarkA = 1;
402 // traverse the new node
404 RetValue = Dch_ObjCheckTfi_rec( p, pObj );
405 // unmark nodes of the choice node
406 for ( pTemp = pRepr; pTemp; pTemp = Aig_ObjEquiv(p, pTemp) )
407 pTemp->fMarkA = 0;
408 return RetValue;
409}
410
422static inline Aig_Obj_t * Aig_ObjGetRepr( Aig_Man_t * p, Aig_Obj_t * pObj )
423{
424 Aig_Obj_t * pRepr;
425 if ( (pRepr = Aig_ObjRepr(p, Aig_Regular(pObj))) )
426 return Aig_NotCond( pRepr, Aig_Regular(pObj)->fPhase ^ pRepr->fPhase ^ Aig_IsComplement(pObj) );
427 return pObj;
428}
429static inline Aig_Obj_t * Aig_ObjChild0CopyRepr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjGetRepr( p, Aig_ObjChild0Copy(pObj) ); }
430static inline Aig_Obj_t * Aig_ObjChild1CopyRepr( Aig_Man_t * p, Aig_Obj_t * pObj ) { return Aig_ObjGetRepr( p, Aig_ObjChild1Copy(pObj) ); }
431
443void Dch_DeriveChoiceAigNode( Aig_Man_t * pAigNew, Aig_Man_t * pAigOld, Aig_Obj_t * pObj, int fSkipRedSupps )
444{
445 Aig_Obj_t * pRepr, * pObjNew, * pReprNew;
446 assert( !Aig_IsComplement(pObj) );
447 // get the representative
448 pRepr = Aig_ObjRepr( pAigOld, pObj );
449 if ( pRepr != NULL && (Aig_ObjIsConst1(pRepr) || Aig_ObjIsCi(pRepr)) )
450 {
451 assert( pRepr->pData != NULL );
452 pObj->pData = Aig_NotCond( (Aig_Obj_t *)pRepr->pData, pObj->fPhase ^ pRepr->fPhase );
453 return;
454 }
455 // get the new node
456 pObjNew = Aig_And( pAigNew,
457 Aig_ObjChild0CopyRepr(pAigNew, pObj),
458 Aig_ObjChild1CopyRepr(pAigNew, pObj) );
459// pObjNew = Aig_ObjGetRepr( pAigNew, pObjNew );
460 while ( 1 )
461 {
462 Aig_Obj_t * pObjNew2 = pObjNew;
463 pObjNew = Aig_ObjGetRepr( pAigNew, pObjNew2 );
464 if ( pObjNew == pObjNew2 )
465 break;
466 }
467// assert( Aig_ObjRepr( pAigNew, pObjNew ) == NULL );
468 // assign the copy
469 assert( pObj->pData == NULL );
470 pObj->pData = pObjNew;
471 // skip those without reprs
472 if ( pRepr == NULL )
473 return;
474 assert( pRepr->Id < pObj->Id );
475 assert( Aig_ObjIsNode(pRepr) );
476 // get the corresponding new nodes
477 pObjNew = Aig_Regular((Aig_Obj_t *)pObj->pData);
478 pReprNew = Aig_Regular((Aig_Obj_t *)pRepr->pData);
479 // skip earlier nodes
480 if ( pReprNew->Id >= pObjNew->Id )
481 return;
482 assert( pReprNew->Id < pObjNew->Id );
483 // set the representatives
484 Aig_ObjSetRepr( pAigNew, pObjNew, pReprNew );
485 // skip used nodes
486 if ( pObjNew->nRefs > 0 )
487 return;
488 assert( pObjNew->nRefs == 0 );
489 // skip choices that can lead to combo loops
490 if ( Dch_ObjCheckTfi( pAigNew, pObjNew, pReprNew ) )
491 return;
492 // don't add choice if structural support of pObjNew and pReprNew differ
493 if ( fSkipRedSupps && Dch_ObjCheckSuppRed(pAigNew, pObjNew, pReprNew) )
494 return;
495 // add choice to the end of the list
496 while ( pAigNew->pEquivs[pReprNew->Id] != NULL )
497 pReprNew = pAigNew->pEquivs[pReprNew->Id];
498 assert( pAigNew->pEquivs[pReprNew->Id] == NULL );
499 pAigNew->pEquivs[pReprNew->Id] = pObjNew;
500}
501Aig_Man_t * Dch_DeriveChoiceAigInt( Aig_Man_t * pAig, int fSkipRedSupps )
502{
503 Aig_Man_t * pChoices;
504 Aig_Obj_t * pObj;
505 int i;
506 // start recording equivalences
507 pChoices = Aig_ManStart( Aig_ManObjNumMax(pAig) );
508 pChoices->pEquivs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) );
509 pChoices->pReprs = ABC_CALLOC( Aig_Obj_t *, Aig_ManObjNumMax(pAig) );
510 // map constants and PIs
511 Aig_ManCleanData( pAig );
512 Aig_ManConst1(pAig)->pData = Aig_ManConst1(pChoices);
513 Aig_ManForEachCi( pAig, pObj, i )
514 pObj->pData = Aig_ObjCreateCi( pChoices );
515 // construct choices for the internal nodes
516 assert( pAig->pReprs != NULL );
517 Aig_ManForEachNode( pAig, pObj, i )
518 Dch_DeriveChoiceAigNode( pChoices, pAig, pObj, fSkipRedSupps );
519 Aig_ManForEachCo( pAig, pObj, i )
520 Aig_ObjCreateCo( pChoices, Aig_ObjChild0CopyRepr(pChoices, pObj) );
521 Aig_ManSetRegNum( pChoices, Aig_ManRegNum(pAig) );
522 return pChoices;
523}
524Aig_Man_t * Dch_DeriveChoiceAig( Aig_Man_t * pAig, int fSkipRedSupps )
525{
526 int fCheck = 0;
527 Aig_Man_t * pChoices, * pTemp;
528 // verify
529 if ( fCheck )
530 Aig_ManCheckReprs( pAig );
531 // compute choices
532 pChoices = Dch_DeriveChoiceAigInt( pAig, fSkipRedSupps );
533 ABC_FREE( pChoices->pReprs );
534 // verify
535 if ( fCheck )
536 Dch_CheckChoices( pChoices, fSkipRedSupps );
537 // find correct topo order with choices
538 pChoices = Aig_ManDupDfs( pTemp = pChoices );
539 Aig_ManStop( pTemp );
540 // verify
541 if ( fCheck )
542 Dch_CheckChoices( pChoices, fSkipRedSupps );
543 return pChoices;
544}
545
549
550
552
#define ABC_CALLOC(type, num)
Definition abc_global.h:265
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
void Aig_ManSetRegNum(Aig_Man_t *p, int nRegs)
Definition aigMan.c:438
Aig_Man_t * Aig_ManDupDfs(Aig_Man_t *p)
Definition aigDup.c:563
void Aig_ManCleanMarkA(Aig_Man_t *p)
Definition aigUtil.c:148
#define Aig_ManForEachObj(p, pObj, i)
Definition aig.h:403
void Aig_ManStop(Aig_Man_t *p)
Definition aigMan.c:187
void Aig_ManIncrementTravId(Aig_Man_t *p)
DECLARATIONS ///.
Definition aigUtil.c:44
#define Aig_ManForEachCi(p, pObj, i)
ITERATORS ///.
Definition aig.h:393
Aig_Obj_t * Aig_And(Aig_Man_t *p, Aig_Obj_t *p0, Aig_Obj_t *p1)
Definition aigOper.c:104
Aig_Obj_t * Aig_ObjCreateCo(Aig_Man_t *p, Aig_Obj_t *pDriver)
Definition aigObj.c:66
struct Aig_Obj_t_ Aig_Obj_t
Definition aig.h:51
Aig_Man_t * Aig_ManStart(int nNodesMax)
DECLARATIONS ///.
Definition aigMan.c:47
#define Aig_ManForEachNode(p, pObj, i)
Definition aig.h:413
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Definition aig.h:50
#define Aig_ManForEachCo(p, pObj, i)
Definition aig.h:398
Aig_Obj_t * Aig_ObjCreateCi(Aig_Man_t *p)
DECLARATIONS ///.
Definition aigObj.c:45
void Aig_ManCleanData(Aig_Man_t *p)
Definition aigUtil.c:205
Aig_Man_t * Dch_DeriveChoiceAig(Aig_Man_t *pAig, int fSkipRedSupps)
Definition dchChoice.c:524
int Aig_ManCheckAcyclic_rec(Aig_Man_t *p, Aig_Obj_t *pNode, int fVerbose)
Definition dchChoice.c:257
int Dch_ObjCheckTfi_rec(Aig_Man_t *p, Aig_Obj_t *pObj)
Definition dchChoice.c:372
int Aig_ManCheckAcyclic(Aig_Man_t *p, int fVerbose)
Definition dchChoice.c:331
int Dch_ObjMarkTfi_rec(Aig_Man_t *p, Aig_Obj_t *pObj)
Definition dchChoice.c:115
int Dch_DeriveChoiceCountEquivs(Aig_Man_t *pAig)
Definition dchChoice.c:89
int Dch_ObjCountSupp(Aig_Man_t *p, Aig_Obj_t *pObj)
Definition dchChoice.c:58
int Dch_DeriveChoiceCountReprs(Aig_Man_t *pAig)
FUNCTION DECLARATIONS ///.
Definition dchChoice.c:75
int Dch_ObjCheckSuppRed(Aig_Man_t *p, Aig_Obj_t *pObj, Aig_Obj_t *pRepr)
Definition dchChoice.c:135
void Dch_DeriveChoiceAigNode(Aig_Man_t *pAigNew, Aig_Man_t *pAigOld, Aig_Obj_t *pObj, int fSkipRedSupps)
Definition dchChoice.c:443
int Dch_ObjCheckTfi(Aig_Man_t *p, Aig_Obj_t *pObj, Aig_Obj_t *pRepr)
Definition dchChoice.c:393
Aig_Man_t * Dch_DeriveChoiceAigInt(Aig_Man_t *pAig, int fSkipRedSupps)
Definition dchChoice.c:501
void Dch_CheckChoices(Aig_Man_t *p, int fSkipRedSupps)
Definition dchChoice.c:206
ABC_NAMESPACE_IMPL_START int Dch_ObjCountSupp_rec(Aig_Man_t *p, Aig_Obj_t *pObj)
DECLARATIONS ///.
Definition dchChoice.c:45
void Aig_ManCheckReprs(Aig_Man_t *p)
Definition dchChoice.c:163
Cube * p
Definition exorList.c:222
int Id
Definition aig.h:85
unsigned int nRefs
Definition aig.h:81
unsigned int fMarkA
Definition aig.h:79
void * pData
Definition aig.h:87
unsigned int fPhase
Definition aig.h:78
#define assert(ex)
Definition util_old.h:213