1 /**CFile****************************************************************
2 
3   FileName    [giaGlitch.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Scalable AIG package.]
8 
9   Synopsis    [Glitch simulation.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: giaGlitch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "gia.h"
22 
23 ABC_NAMESPACE_IMPL_START
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 ///                        DECLARATIONS                              ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 typedef struct Gli_Obj_t_ Gli_Obj_t;
31 struct Gli_Obj_t_
32 {
33     unsigned       fTerm    :  1;    // terminal node
34     unsigned       fPhase   :  1;    // value under 000 pattern
35     unsigned       fPhase2  :  1;    // value under 000 pattern
36     unsigned       fMark    :  1;    // user-controlled mark
37     unsigned       nFanins  :  3;    // the number of fanins
38     unsigned       nFanouts : 25;    // total number of fanouts
39     unsigned       Handle;           // ID of the node
40     word *         pTruth;           // truth table of the node
41     unsigned       uSimInfo;         // simulation info of the node
42     union
43     {
44         int        iFanin;           // the number of fanins added
45         int        nSwitches;        // the number of switches
46     };
47     union
48     {
49         int        iFanout;          // the number of fanouts added
50         int        nGlitches;        // the number of glitches ( nGlitches >= nSwitches )
51     };
52     int            Fanios[0];        // the array of fanins/fanouts
53 };
54 
55 typedef struct Gli_Man_t_ Gli_Man_t;
56 struct Gli_Man_t_
57 {
58     Vec_Int_t *    vCis;             // the vector of CIs (PIs + LOs)
59     Vec_Int_t *    vCos;             // the vector of COs (POs + LIs)
60     Vec_Int_t *    vCisChanged;      // the changed CIs
61     Vec_Int_t *    vAffected;        // the affected nodes
62     Vec_Int_t *    vFrontier;        // the fanouts of these nodes
63     int            nObjs;            // the number of objects
64     int            nRegs;            // the number of registers
65     int            nTravIds;         // traversal ID of the network
66     int            iObjData;         // pointer to the current data
67     int            nObjData;         // the size of array to store the logic network
68     int *          pObjData;         // the internal nodes
69     unsigned *     pSimInfoPrev;     // previous values of the CIs
70 };
71 
72 
Gli_ManCiNum(Gli_Man_t * p)73 static inline int         Gli_ManCiNum( Gli_Man_t * p )            { return Vec_IntSize(p->vCis);                                         }
Gli_ManCoNum(Gli_Man_t * p)74 static inline int         Gli_ManCoNum( Gli_Man_t * p )            { return Vec_IntSize(p->vCos);                                         }
Gli_ManPiNum(Gli_Man_t * p)75 static inline int         Gli_ManPiNum( Gli_Man_t * p )            { return Vec_IntSize(p->vCis) - p->nRegs;                              }
Gli_ManPoNum(Gli_Man_t * p)76 static inline int         Gli_ManPoNum( Gli_Man_t * p )            { return Vec_IntSize(p->vCos) - p->nRegs;                              }
Gli_ManRegNum(Gli_Man_t * p)77 static inline int         Gli_ManRegNum( Gli_Man_t * p )           { return p->nRegs;                                                     }
Gli_ManObjNum(Gli_Man_t * p)78 static inline int         Gli_ManObjNum( Gli_Man_t * p )           { return p->nObjs;                                                     }
Gli_ManNodeNum(Gli_Man_t * p)79 static inline int         Gli_ManNodeNum( Gli_Man_t * p )          { return p->nObjs - Vec_IntSize(p->vCis) - Vec_IntSize(p->vCos);       }
80 
Gli_ManObj(Gli_Man_t * p,int v)81 static inline Gli_Obj_t * Gli_ManObj( Gli_Man_t * p, int v )       { return (Gli_Obj_t *)(p->pObjData + v);                               }
Gli_ManCi(Gli_Man_t * p,int v)82 static inline Gli_Obj_t * Gli_ManCi( Gli_Man_t * p, int v )        { return Gli_ManObj( p, Vec_IntEntry(p->vCis,v) );                     }
Gli_ManCo(Gli_Man_t * p,int v)83 static inline Gli_Obj_t * Gli_ManCo( Gli_Man_t * p, int v )        { return Gli_ManObj( p, Vec_IntEntry(p->vCos,v) );                     }
Gli_ManPi(Gli_Man_t * p,int v)84 static inline Gli_Obj_t * Gli_ManPi( Gli_Man_t * p, int v )        { assert( v < Gli_ManPiNum(p) );  return Gli_ManCi( p, v );            }
Gli_ManPo(Gli_Man_t * p,int v)85 static inline Gli_Obj_t * Gli_ManPo( Gli_Man_t * p, int v )        { assert( v < Gli_ManPoNum(p) );  return Gli_ManCo( p, v );            }
Gli_ManRo(Gli_Man_t * p,int v)86 static inline Gli_Obj_t * Gli_ManRo( Gli_Man_t * p, int v )        { assert( v < Gli_ManRegNum(p) ); return Gli_ManCi( p, Gli_ManRegNum(p)+v );      }
Gli_ManRi(Gli_Man_t * p,int v)87 static inline Gli_Obj_t * Gli_ManRi( Gli_Man_t * p, int v )        { assert( v < Gli_ManRegNum(p) ); return Gli_ManCo( p, Gli_ManRegNum(p)+v );      }
88 
Gli_ObjIsTerm(Gli_Obj_t * pObj)89 static inline int         Gli_ObjIsTerm( Gli_Obj_t * pObj )        { return pObj->fTerm;                                                  }
Gli_ObjIsCi(Gli_Obj_t * pObj)90 static inline int         Gli_ObjIsCi( Gli_Obj_t * pObj )          { return pObj->fTerm && pObj->nFanins == 0;                            }
Gli_ObjIsCo(Gli_Obj_t * pObj)91 static inline int         Gli_ObjIsCo( Gli_Obj_t * pObj )          { return pObj->fTerm && pObj->nFanins == 1;                            }
Gli_ObjIsNode(Gli_Obj_t * pObj)92 static inline int         Gli_ObjIsNode( Gli_Obj_t * pObj )        { return!pObj->fTerm;                                                  }
93 
Gli_ObjFaninNum(Gli_Obj_t * pObj)94 static inline int         Gli_ObjFaninNum( Gli_Obj_t * pObj )      { return pObj->nFanins;                                                }
Gli_ObjFanoutNum(Gli_Obj_t * pObj)95 static inline int         Gli_ObjFanoutNum( Gli_Obj_t * pObj )     { return pObj->nFanouts;                                               }
Gli_ObjSize(Gli_Obj_t * pObj)96 static inline int         Gli_ObjSize( Gli_Obj_t * pObj )          { return sizeof(Gli_Obj_t) / 4 + pObj->nFanins + pObj->nFanouts;       }
97 
Gli_ObjFanin(Gli_Obj_t * pObj,int i)98 static inline Gli_Obj_t * Gli_ObjFanin( Gli_Obj_t * pObj, int i )  { return (Gli_Obj_t *)(((int *)pObj) - pObj->Fanios[i]);               }
Gli_ObjFanout(Gli_Obj_t * pObj,int i)99 static inline Gli_Obj_t * Gli_ObjFanout( Gli_Obj_t * pObj, int i ) { return (Gli_Obj_t *)(((int *)pObj) + pObj->Fanios[pObj->nFanins+i]); }
100 
101 #define Gli_ManForEachObj( p, pObj, i )                 \
102     for ( i = 0; (i < p->nObjData) && (pObj = Gli_ManObj(p,i)); i += Gli_ObjSize(pObj) )
103 #define Gli_ManForEachNode( p, pObj, i )                \
104     for ( i = 0; (i < p->nObjData) && (pObj = Gli_ManObj(p,i)); i += Gli_ObjSize(pObj) ) if ( Gli_ObjIsTerm(pObj) ) {} else
105 
106 #define Gli_ManForEachEntry( vVec, p, pObj, i )         \
107     for ( i = 0; (i < Vec_IntSize(vVec)) && (pObj = Gli_ManObj(p,Vec_IntEntry(vVec,i))); i++ )
108 #define Gli_ManForEachCi( p, pObj, i )                  \
109     for ( i = 0; (i < Vec_IntSize(p->vCis)) && (pObj = Gli_ManObj(p,Vec_IntEntry(p->vCis,i))); i++ )
110 #define Gli_ManForEachCo( p, pObj, i )                  \
111     for ( i = 0; (i < Vec_IntSize(p->vCos)) && (pObj = Gli_ManObj(p,Vec_IntEntry(p->vCos,i))); i++ )
112 
113 #define Gli_ManForEachPi( p, pObj, i )                                  \
114     for ( i = 0; (i < Gli_ManPiNum(p)) && ((pObj) = Gli_ManCi(p, i)); i++ )
115 #define Gli_ManForEachPo( p, pObj, i )                                  \
116     for ( i = 0; (i < Gli_ManPoNum(p)) && ((pObj) = Gli_ManCo(p, i)); i++ )
117 #define Gli_ManForEachRo( p, pObj, i )                                  \
118     for ( i = 0; (i < Gli_ManRegNum(p)) && ((pObj) = Gli_ManCi(p, Gli_ManPiNum(p)+i)); i++ )
119 #define Gli_ManForEachRi( p, pObj, i )                                  \
120     for ( i = 0; (i < Gli_ManRegNum(p)) && ((pObj) = Gli_ManCo(p, Gli_ManPoNum(p)+i)); i++ )
121 #define Gli_ManForEachRiRo( p, pObjRi, pObjRo, i )                      \
122     for ( i = 0; (i < Gli_ManRegNum(p)) && ((pObjRi) = Gli_ManCo(p, Gli_ManPoNum(p)+i)) && ((pObjRo) = Gli_ManCi(p, Gli_ManPiNum(p)+i)); i++ )
123 
124 #define Gli_ObjForEachFanin( pObj, pNext, i )           \
125     for ( i = 0; (i < (int)pObj->nFanins) && (pNext = Gli_ObjFanin(pObj,i)); i++ )
126 #define Gli_ObjForEachFanout( pObj, pNext, i )          \
127     for ( i = 0; (i < (int)pObj->nFanouts) && (pNext = Gli_ObjFanout(pObj,i)); i++ )
128 
129 ////////////////////////////////////////////////////////////////////////
130 ///                     FUNCTION DEFINITIONS                         ///
131 ////////////////////////////////////////////////////////////////////////
132 
133 /**Function*************************************************************
134 
135   Synopsis    [Creates logic network.]
136 
137   Description []
138 
139   SideEffects []
140 
141   SeeAlso     []
142 
143 ***********************************************************************/
Gli_ManAlloc(int nObjs,int nRegs,int nFanioPairs)144 Gli_Man_t * Gli_ManAlloc( int nObjs, int nRegs, int nFanioPairs )
145 {
146     Gli_Man_t * p;
147     p = (Gli_Man_t *)ABC_CALLOC( int, (sizeof(Gli_Man_t) / 4) + (sizeof(Gli_Obj_t) / 4) * nObjs + 2 * nFanioPairs );
148     p->nRegs = nRegs;
149     p->vCis = Vec_IntAlloc( 1000 );
150     p->vCos = Vec_IntAlloc( 1000 );
151     p->vCisChanged = Vec_IntAlloc( 1000 );
152     p->vAffected = Vec_IntAlloc( 1000 );
153     p->vFrontier = Vec_IntAlloc( 1000 );
154     p->nObjData = (sizeof(Gli_Obj_t) / 4) * nObjs + 2 * nFanioPairs;
155     p->pObjData = (int *)(p + 1);
156     return p;
157 }
158 
159 /**Function*************************************************************
160 
161   Synopsis    [Deletes logic network.]
162 
163   Description []
164 
165   SideEffects []
166 
167   SeeAlso     []
168 
169 ***********************************************************************/
Gli_ManStop(Gli_Man_t * p)170 void Gli_ManStop( Gli_Man_t * p )
171 {
172     Vec_IntFree( p->vCis );
173     Vec_IntFree( p->vCos );
174     Vec_IntFree( p->vCisChanged );
175     Vec_IntFree( p->vAffected );
176     Vec_IntFree( p->vFrontier );
177     ABC_FREE( p->pSimInfoPrev );
178     ABC_FREE( p );
179 }
180 
181 /**Function*************************************************************
182 
183   Synopsis    [Checks logic network.]
184 
185   Description []
186 
187   SideEffects []
188 
189   SeeAlso     []
190 
191 ***********************************************************************/
Gli_ManPrintObjects(Gli_Man_t * p)192 void Gli_ManPrintObjects( Gli_Man_t * p )
193 {
194     Gli_Obj_t * pObj, * pNext;
195     int i, k;
196     Gli_ManForEachObj( p, pObj, i )
197     {
198         printf( "Node %d \n", pObj->Handle );
199         printf( "Fanins: " );
200         Gli_ObjForEachFanin( pObj, pNext, k )
201             printf( "%d ", pNext->Handle );
202         printf( "\n" );
203         printf( "Fanouts: " );
204         Gli_ObjForEachFanout( pObj, pNext, k )
205             printf( "%d ", pNext->Handle );
206         printf( "\n" );
207     }
208 }
209 
210 /**Function*************************************************************
211 
212   Synopsis    [Checks logic network.]
213 
214   Description []
215 
216   SideEffects []
217 
218   SeeAlso     []
219 
220 ***********************************************************************/
Gli_ManFinalize(Gli_Man_t * p)221 void Gli_ManFinalize( Gli_Man_t * p )
222 {
223     Gli_Obj_t * pObj;
224     int i;
225     assert( p->iObjData == p->nObjData );
226     Gli_ManForEachObj( p, pObj, i )
227     {
228         assert( pObj->iFanin == (int)pObj->nFanins );
229         assert( pObj->iFanout == (int)pObj->nFanouts );
230         pObj->iFanin = 0;
231         pObj->iFanout = 0;
232     }
233 }
234 
235 /**Function*************************************************************
236 
237   Synopsis    [Creates fanin/fanout pair.]
238 
239   Description []
240 
241   SideEffects []
242 
243   SeeAlso     []
244 
245 ***********************************************************************/
Gli_ObjAddFanin(Gli_Obj_t * pObj,Gli_Obj_t * pFanin)246 void Gli_ObjAddFanin( Gli_Obj_t * pObj, Gli_Obj_t * pFanin )
247 {
248     assert( pObj->iFanin < (int)pObj->nFanins );
249     assert( pFanin->iFanout < (int)pFanin->nFanouts );
250     pFanin->Fanios[pFanin->nFanins + pFanin->iFanout++] =
251     pObj->Fanios[pObj->iFanin++] = pObj->Handle - pFanin->Handle;
252 }
253 
254 /**Function*************************************************************
255 
256   Synopsis    [Allocates object.]
257 
258   Description []
259 
260   SideEffects []
261 
262   SeeAlso     []
263 
264 ***********************************************************************/
Gli_ObjAlloc(Gli_Man_t * p,int nFanins,int nFanouts)265 Gli_Obj_t * Gli_ObjAlloc( Gli_Man_t * p, int nFanins, int nFanouts )
266 {
267     Gli_Obj_t * pObj;
268     pObj = Gli_ManObj( p, p->iObjData );
269     pObj->Handle   = p->iObjData;
270     pObj->nFanins  = nFanins;
271     pObj->nFanouts = nFanouts;
272     p->iObjData += Gli_ObjSize( pObj );
273     p->nObjs++;
274     return pObj;
275 }
276 
277 /**Function*************************************************************
278 
279   Synopsis    [Creates CI.]
280 
281   Description []
282 
283   SideEffects []
284 
285   SeeAlso     []
286 
287 ***********************************************************************/
Gli_ManCreateCi(Gli_Man_t * p,int nFanouts)288 int Gli_ManCreateCi( Gli_Man_t * p, int nFanouts )
289 {
290     Gli_Obj_t * pObj;
291     pObj = Gli_ObjAlloc( p, 0, nFanouts );
292     pObj->fTerm = 1;
293     Vec_IntPush( p->vCis, pObj->Handle );
294     return pObj->Handle;
295 }
296 
297 /**Function*************************************************************
298 
299   Synopsis    [Creates CO.]
300 
301   Description []
302 
303   SideEffects []
304 
305   SeeAlso     []
306 
307 ***********************************************************************/
Gli_ManCreateCo(Gli_Man_t * p,int iFanin)308 int Gli_ManCreateCo( Gli_Man_t * p, int iFanin )
309 {
310     Gli_Obj_t * pObj, * pFanin;
311     pObj = Gli_ObjAlloc( p, 1, 0 );
312     pObj->fTerm = 1;
313     pFanin = Gli_ManObj( p, iFanin );
314     Gli_ObjAddFanin( pObj, pFanin );
315     pObj->fPhase = pObj->fPhase2 = pFanin->fPhase;
316     Vec_IntPush( p->vCos, pObj->Handle );
317     return pObj->Handle;
318 }
319 
320 /**Function*************************************************************
321 
322   Synopsis    [Creates node.]
323 
324   Description []
325 
326   SideEffects []
327 
328   SeeAlso     []
329 
330 ***********************************************************************/
Gli_NodeComputeValue(Gli_Obj_t * pNode)331 static inline int Gli_NodeComputeValue( Gli_Obj_t * pNode )
332 {
333     int i, Phase = 0;
334     for ( i = 0; i < (int)pNode->nFanins; i++ )
335         Phase |= (Gli_ObjFanin(pNode, i)->fPhase << i);
336     return Abc_InfoHasBit( (unsigned *)pNode->pTruth, Phase );
337 }
338 
339 /**Function*************************************************************
340 
341   Synopsis    [Creates node.]
342 
343   Description []
344 
345   SideEffects []
346 
347   SeeAlso     []
348 
349 ***********************************************************************/
Gli_NodeComputeValue2(Gli_Obj_t * pNode)350 static inline int Gli_NodeComputeValue2( Gli_Obj_t * pNode )
351 {
352     int i, Phase = 0;
353     for ( i = 0; i < (int)pNode->nFanins; i++ )
354         Phase |= (Gli_ObjFanin(pNode, i)->fPhase2 << i);
355     return Abc_InfoHasBit( (unsigned *)pNode->pTruth, Phase );
356 }
357 
358 /**Function*************************************************************
359 
360   Synopsis    [Creates node.]
361 
362   Description []
363 
364   SideEffects []
365 
366   SeeAlso     []
367 
368 ***********************************************************************/
Gli_ManCreateNode(Gli_Man_t * p,Vec_Int_t * vFanins,int nFanouts,word * pGateTruth)369 int Gli_ManCreateNode( Gli_Man_t * p, Vec_Int_t * vFanins, int nFanouts, word * pGateTruth )
370 {
371     Gli_Obj_t * pObj, * pFanin;
372     int i;
373     assert( Vec_IntSize(vFanins) <= 16 );
374     pObj = Gli_ObjAlloc( p, Vec_IntSize(vFanins), nFanouts );
375     Gli_ManForEachEntry( vFanins, p, pFanin, i )
376         Gli_ObjAddFanin( pObj, pFanin );
377     pObj->pTruth = pGateTruth;
378     pObj->fPhase = pObj->fPhase2 = Gli_NodeComputeValue( pObj );
379     return pObj->Handle;
380 }
381 
382 /**Function*************************************************************
383 
384   Synopsis    [Returns the number of switches of the node.]
385 
386   Description []
387 
388   SideEffects []
389 
390   SeeAlso     []
391 
392 ***********************************************************************/
Gli_ObjNumSwitches(Gli_Man_t * p,int iNode)393 int Gli_ObjNumSwitches( Gli_Man_t * p, int iNode )
394 {
395     return Gli_ManObj( p, iNode )->nSwitches;
396 }
397 
398 /**Function*************************************************************
399 
400   Synopsis    [Returns the number of glitches of the node.]
401 
402   Description []
403 
404   SideEffects []
405 
406   SeeAlso     []
407 
408 ***********************************************************************/
Gli_ObjNumGlitches(Gli_Man_t * p,int iNode)409 int Gli_ObjNumGlitches( Gli_Man_t * p, int iNode )
410 {
411     return Gli_ManObj( p, iNode )->nGlitches;
412 }
413 
414 
415 /**Function*************************************************************
416 
417   Synopsis    [Sets random info at the PIs and collects changed PIs.]
418 
419   Description []
420 
421   SideEffects []
422 
423   SeeAlso     []
424 
425 ***********************************************************************/
Gli_ManSetPiRandom(Gli_Man_t * p,float PiTransProb)426 void Gli_ManSetPiRandom( Gli_Man_t * p, float PiTransProb )
427 {
428     Gli_Obj_t * pObj;
429     float Multi = 1.0 / (1 << 16);
430     int i;
431     assert( 0.0 < PiTransProb && PiTransProb < 1.0 );
432     Vec_IntClear( p->vCisChanged );
433     Gli_ManForEachCi( p, pObj, i )
434         if ( Multi * (Gia_ManRandom(0) & 0xffff) < PiTransProb )
435         {
436             Vec_IntPush( p->vCisChanged, pObj->Handle );
437             pObj->fPhase  ^= 1;
438             pObj->fPhase2 ^= 1;
439             pObj->nSwitches++;
440             pObj->nGlitches++;
441         }
442 }
443 
444 /**Function*************************************************************
445 
446   Synopsis    [Sets random info at the PIs and collects changed PIs.]
447 
448   Description []
449 
450   SideEffects []
451 
452   SeeAlso     []
453 
454 ***********************************************************************/
Gli_ManSetPiFromSaved(Gli_Man_t * p,int iBit)455 void Gli_ManSetPiFromSaved( Gli_Man_t * p, int iBit )
456 {
457     Gli_Obj_t * pObj;
458     int i;
459     Vec_IntClear( p->vCisChanged );
460     Gli_ManForEachCi( p, pObj, i )
461         if ( (p->pSimInfoPrev[i] ^ pObj->uSimInfo) & (1 << iBit) )
462         {
463             Vec_IntPush( p->vCisChanged, pObj->Handle );
464             pObj->fPhase  ^= 1;
465             pObj->fPhase2 ^= 1;
466             pObj->nSwitches++;
467             pObj->nGlitches++;
468         }
469 }
470 
471 /**Function*************************************************************
472 
473   Synopsis    [Computes switching activity of each node.]
474 
475   Description []
476 
477   SideEffects []
478 
479   SeeAlso     []
480 
481 ***********************************************************************/
Gli_ManSwitching(Gli_Man_t * p)482 void Gli_ManSwitching( Gli_Man_t * p )
483 {
484     Gli_Obj_t * pThis;
485     int i;
486     Gli_ManForEachNode( p, pThis, i )
487     {
488         if ( ((int)pThis->fPhase) == Gli_NodeComputeValue(pThis) )
489             continue;
490         pThis->fPhase ^= 1;
491         pThis->nSwitches++;
492     }
493 }
494 
495 /**Function*************************************************************
496 
497   Synopsis    [Computes glitching activity of each node.]
498 
499   Description []
500 
501   SideEffects []
502 
503   SeeAlso     []
504 
505 ***********************************************************************/
Gli_ManGlitching(Gli_Man_t * p)506 void Gli_ManGlitching( Gli_Man_t * p )
507 {
508     Gli_Obj_t * pThis, * pFanout;//, * pOther = Gli_ManObj(p, 41);
509     int i, k, Handle;
510 //    Gli_ManForEachObj( p, pThis, i )
511 //        assert( pThis->fMark == 0 );
512     // start the array of affected nodes
513     Vec_IntClear( p->vAffected );
514     Vec_IntForEachEntry( p->vCisChanged, Handle, i )
515         Vec_IntPush( p->vAffected, Handle );
516     // iteration propagation
517     while ( Vec_IntSize(p->vAffected) > 0 )
518     {
519         // compute the frontier
520         Vec_IntClear( p->vFrontier );
521         Gli_ManForEachEntry( p->vAffected, p, pThis, i )
522         {
523             Gli_ObjForEachFanout( pThis, pFanout, k )
524             {
525                 if ( Gli_ObjIsCo(pFanout) )
526                     continue;
527                 if ( pFanout->fMark )
528                     continue;
529                 pFanout->fMark = 1;
530                 Vec_IntPush( p->vFrontier, pFanout->Handle );
531             }
532         }
533         // compute the next set of affected nodes
534         Vec_IntClear( p->vAffected );
535         Gli_ManForEachEntry( p->vFrontier, p, pThis, i )
536         {
537             pThis->fMark = 0;
538             if ( ((int)pThis->fPhase2) == Gli_NodeComputeValue2(pThis) )
539                 continue;
540             pThis->fPhase2 ^= 1;
541             pThis->nGlitches++;
542             Vec_IntPush( p->vAffected, pThis->Handle );
543         }
544     }
545 }
546 
547 /**Function*************************************************************
548 
549   Synopsis    [Checks that the resulting values are the same.]
550 
551   Description []
552 
553   SideEffects []
554 
555   SeeAlso     []
556 
557 ***********************************************************************/
Gli_ManVerify(Gli_Man_t * p)558 void Gli_ManVerify( Gli_Man_t * p )
559 {
560     Gli_Obj_t * pObj;
561     int i;
562     Gli_ManForEachObj( p, pObj, i )
563     {
564         assert( pObj->fPhase == pObj->fPhase2 );
565         assert( pObj->nGlitches >= pObj->nSwitches );
566     }
567 }
568 
569 /**Function*************************************************************
570 
571   Synopsis    [Simulates one node.]
572 
573   Description []
574 
575   SideEffects []
576 
577   SeeAlso     []
578 
579 ***********************************************************************/
Gli_ManSimulateSeqNode(Gli_Man_t * p,Gli_Obj_t * pNode)580 unsigned Gli_ManSimulateSeqNode( Gli_Man_t * p, Gli_Obj_t * pNode )
581 {
582     unsigned pSimInfos[6], Result = 0;
583     int nFanins = Gli_ObjFaninNum(pNode);
584     int i, k, Phase;
585     Gli_Obj_t * pFanin;
586     assert( nFanins <= 16 );
587     Gli_ObjForEachFanin( pNode, pFanin, i )
588         pSimInfos[i] = pFanin->uSimInfo;
589     for ( i = 0; i < 32; i++ )
590     {
591         Phase = 0;
592         for ( k = 0; k < nFanins; k++ )
593             if ( (pSimInfos[k] >> i) & 1 )
594                 Phase |= (1 << k);
595         if ( Abc_InfoHasBit( (unsigned *)pNode->pTruth, Phase ) )
596             Result |= (1 << i);
597     }
598     return Result;
599 }
600 
601 /**Function*************************************************************
602 
603   Synopsis    [Simulates one node.]
604 
605   Description []
606 
607   SideEffects []
608 
609   SeeAlso     []
610 
611 ***********************************************************************/
Gli_ManUpdateRandomInput(unsigned uInfo,float PiTransProb)612 static inline unsigned Gli_ManUpdateRandomInput( unsigned uInfo, float PiTransProb )
613 {
614     float Multi = 1.0 / (1 << 16);
615     int i;
616     if ( PiTransProb == 0.5 )
617         return Gia_ManRandom(0);
618     for ( i = 0; i < 32; i++ )
619         if ( Multi * (Gia_ManRandom(0) & 0xffff) < PiTransProb )
620             uInfo ^= (1 << i);
621     return uInfo;
622 }
623 
624 /**Function*************************************************************
625 
626   Synopsis    [Simulates sequential network randomly for the given number of frames.]
627 
628   Description []
629 
630   SideEffects []
631 
632   SeeAlso     []
633 
634 ***********************************************************************/
Gli_ManSimulateSeqPref(Gli_Man_t * p,int nPref)635 void Gli_ManSimulateSeqPref( Gli_Man_t * p, int nPref )
636 {
637     Gli_Obj_t * pObj, * pObjRi, * pObjRo;
638     int i, f;
639     // initialize simulation data
640     Gli_ManForEachPi( p, pObj, i )
641         pObj->uSimInfo = Gli_ManUpdateRandomInput( pObj->uSimInfo, 0.5 );
642     Gli_ManForEachRo( p, pObj, i )
643         pObj->uSimInfo = 0;
644     for ( f = 0; f < nPref; f++ )
645     {
646         // simulate one frame
647         Gli_ManForEachNode( p, pObj, i )
648             pObj->uSimInfo = Gli_ManSimulateSeqNode( p, pObj );
649         Gli_ManForEachRi( p, pObj, i )
650             pObj->uSimInfo = Gli_ObjFanin(pObj, 0)->uSimInfo;
651         // initialize the next frame
652         Gli_ManForEachPi( p, pObj, i )
653             pObj->uSimInfo = Gli_ManUpdateRandomInput( pObj->uSimInfo, 0.5 );
654         Gli_ManForEachRiRo( p, pObjRi, pObjRo, i )
655             pObjRo->uSimInfo = pObjRi->uSimInfo;
656     }
657     // save simulation data after nPref timeframes
658     if ( p->pSimInfoPrev == NULL )
659         p->pSimInfoPrev = ABC_ALLOC( unsigned, Gli_ManCiNum(p) );
660     Gli_ManForEachCi( p, pObj, i )
661         p->pSimInfoPrev[i] = pObj->uSimInfo;
662 }
663 
664 /**Function*************************************************************
665 
666   Synopsis    [Initialized object values to be one pattern in the saved data.]
667 
668   Description []
669 
670   SideEffects []
671 
672   SeeAlso     []
673 
674 ***********************************************************************/
Gli_ManSetDataSaved(Gli_Man_t * p,int iBit)675 void Gli_ManSetDataSaved( Gli_Man_t * p, int iBit )
676 {
677     Gli_Obj_t * pObj;
678     int i;
679     Gli_ManForEachCi( p, pObj, i )
680         pObj->fPhase = pObj->fPhase2 = ((p->pSimInfoPrev[i] >> iBit) & 1);
681     Gli_ManForEachNode( p, pObj, i )
682         pObj->fPhase = pObj->fPhase2 = Gli_NodeComputeValue( pObj );
683 }
684 
685 /**Function*************************************************************
686 
687   Synopsis    [Sets random info at the PIs and collects changed PIs.]
688 
689   Description []
690 
691   SideEffects []
692 
693   SeeAlso     []
694 
695 ***********************************************************************/
Gli_ManSetPiRandomSeq(Gli_Man_t * p,float PiTransProb)696 void Gli_ManSetPiRandomSeq( Gli_Man_t * p, float PiTransProb )
697 {
698     Gli_Obj_t * pObj, * pObjRi;
699     float Multi = 1.0 / (1 << 16);
700     int i;
701     assert( 0.0 < PiTransProb && PiTransProb < 1.0 );
702     // transfer data to the COs
703     Gli_ManForEachCo( p, pObj, i )
704         pObj->fPhase = pObj->fPhase2 = Gli_ObjFanin(pObj, 0)->fPhase;
705     // set changed PIs
706     Vec_IntClear( p->vCisChanged );
707     Gli_ManForEachPi( p, pObj, i )
708         if ( Multi * (Gia_ManRandom(0) & 0xffff) < PiTransProb )
709         {
710             Vec_IntPush( p->vCisChanged, pObj->Handle );
711             pObj->fPhase  ^= 1;
712             pObj->fPhase2 ^= 1;
713             pObj->nSwitches++;
714             pObj->nGlitches++;
715         }
716     // set changed ROs
717     Gli_ManForEachRiRo( p, pObjRi, pObj, i )
718         if ( pObjRi->fPhase != pObj->fPhase )
719         {
720             Vec_IntPush( p->vCisChanged, pObj->Handle );
721             pObj->fPhase  ^= 1;
722             pObj->fPhase2 ^= 1;
723             pObj->nSwitches++;
724             pObj->nGlitches++;
725         }
726 
727 }
728 
729 /**Function*************************************************************
730 
731   Synopsis    [Computes glitching activity of each node.]
732 
733   Description []
734 
735   SideEffects []
736 
737   SeeAlso     []
738 
739 ***********************************************************************/
Gli_ManSwitchesAndGlitches(Gli_Man_t * p,int nPatterns,float PiTransProb,int fVerbose)740 void Gli_ManSwitchesAndGlitches( Gli_Man_t * p, int nPatterns, float PiTransProb, int fVerbose )
741 {
742     int i, k;
743     abctime clk = Abc_Clock();
744     Gia_ManRandom( 1 );
745     Gli_ManFinalize( p );
746     if ( p->nRegs == 0 )
747     {
748         for ( i = 0; i < nPatterns; i++ )
749         {
750             Gli_ManSetPiRandom( p, PiTransProb );
751             Gli_ManSwitching( p );
752             Gli_ManGlitching( p );
753 //            Gli_ManVerify( p );
754         }
755     }
756     else
757     {
758         int nIters = Abc_BitWordNum(nPatterns);
759         Gli_ManSimulateSeqPref( p, 16 );
760         for ( i = 0; i < 32; i++ )
761         {
762             Gli_ManSetDataSaved( p, i );
763             for ( k = 0; k < nIters; k++ )
764             {
765                 Gli_ManSetPiRandomSeq( p, PiTransProb );
766                 Gli_ManSwitching( p );
767                 Gli_ManGlitching( p );
768 //                Gli_ManVerify( p );
769             }
770         }
771     }
772     if ( fVerbose )
773     {
774         printf( "Simulated %d patterns.  Input transition probability %.2f.  ", nPatterns, PiTransProb );
775         ABC_PRMn( "Memory", 4*p->nObjData );
776         ABC_PRT( "Time", Abc_Clock() - clk );
777     }
778 }
779 
780 ////////////////////////////////////////////////////////////////////////
781 ///                       END OF FILE                                ///
782 ////////////////////////////////////////////////////////////////////////
783 
784 
785 ABC_NAMESPACE_IMPL_END
786 
787