1 /**CFile****************************************************************
2 
3   FileName    [saigSwitch.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Sequential AIG package.]
8 
9   Synopsis    [Returns switching propabilities.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: saigSwitch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "saig.h"
22 
23 #include "base/main/main.h"
24 
25 ABC_NAMESPACE_IMPL_START
26 
27 
28 ////////////////////////////////////////////////////////////////////////
29 ///                        DECLARATIONS                              ///
30 ////////////////////////////////////////////////////////////////////////
31 
32 typedef struct Saig_SimObj_t_ Saig_SimObj_t;
33 struct Saig_SimObj_t_
34 {
35     int      iFan0;
36     int      iFan1;
37     unsigned Type   :  8;
38     unsigned Number : 24;
39     unsigned pData[1];
40 };
41 
Saig_SimObjFaninC0(Saig_SimObj_t * pObj)42 static inline int Saig_SimObjFaninC0( Saig_SimObj_t * pObj )  { return pObj->iFan0 & 1;  }
Saig_SimObjFaninC1(Saig_SimObj_t * pObj)43 static inline int Saig_SimObjFaninC1( Saig_SimObj_t * pObj )  { return pObj->iFan1 & 1;  }
Saig_SimObjFanin0(Saig_SimObj_t * pObj)44 static inline int Saig_SimObjFanin0( Saig_SimObj_t * pObj )   { return pObj->iFan0 >> 1; }
Saig_SimObjFanin1(Saig_SimObj_t * pObj)45 static inline int Saig_SimObjFanin1( Saig_SimObj_t * pObj )   { return pObj->iFan1 >> 1; }
46 
47 //typedef struct Aig_CMan_t_ Aig_CMan_t;
48 
49 //static Aig_CMan_t * Aig_CManCreate( Aig_Man_t * p );
50 
51 ////////////////////////////////////////////////////////////////////////
52 ///                     FUNCTION DEFINITIONS                         ///
53 ////////////////////////////////////////////////////////////////////////
54 
55 /**Function*************************************************************
56 
57   Synopsis    [Creates fast simulation manager.]
58 
59   Description []
60 
61   SideEffects []
62 
63   SeeAlso     []
64 
65 ***********************************************************************/
Saig_ManCreateMan(Aig_Man_t * p)66 Saig_SimObj_t * Saig_ManCreateMan( Aig_Man_t * p )
67 {
68     Saig_SimObj_t * pAig, * pEntry;
69     Aig_Obj_t * pObj;
70     int i;
71     pAig = ABC_CALLOC( Saig_SimObj_t, Aig_ManObjNumMax(p)+1 );
72 //    printf( "Allocating %7.2f MB.\n", 1.0 * sizeof(Saig_SimObj_t) * (Aig_ManObjNumMax(p)+1)/(1<<20) );
73     Aig_ManForEachObj( p, pObj, i )
74     {
75         pEntry = pAig + i;
76         pEntry->Type = pObj->Type;
77         if ( Aig_ObjIsCi(pObj) || i == 0 )
78         {
79             if ( Saig_ObjIsLo(p, pObj) )
80             {
81                 pEntry->iFan0 = (Saig_ObjLoToLi(p, pObj)->Id << 1);
82                 pEntry->iFan1 = -1;
83             }
84             continue;
85         }
86         pEntry->iFan0 = (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj);
87         if ( Aig_ObjIsCo(pObj) )
88             continue;
89         assert( Aig_ObjIsNode(pObj) );
90         pEntry->iFan1 = (Aig_ObjFaninId1(pObj) << 1) | Aig_ObjFaninC1(pObj);
91     }
92     pEntry = pAig + Aig_ManObjNumMax(p);
93     pEntry->Type = AIG_OBJ_VOID;
94     return pAig;
95 }
96 
97 /**Function*************************************************************
98 
99   Synopsis    [Simulated one node.]
100 
101   Description []
102 
103   SideEffects []
104 
105   SeeAlso     []
106 
107 ***********************************************************************/
Saig_ManSimulateNode2(Saig_SimObj_t * pAig,Saig_SimObj_t * pObj)108 static inline void Saig_ManSimulateNode2( Saig_SimObj_t * pAig, Saig_SimObj_t * pObj )
109 {
110     Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pObj );
111     Saig_SimObj_t * pObj1 = pAig + Saig_SimObjFanin1( pObj );
112     if ( Saig_SimObjFaninC0(pObj) && Saig_SimObjFaninC1(pObj) )
113         pObj->pData[0] = ~(pObj0->pData[0] | pObj1->pData[0]);
114     else if ( Saig_SimObjFaninC0(pObj) && !Saig_SimObjFaninC1(pObj) )
115         pObj->pData[0] = (~pObj0->pData[0] & pObj1->pData[0]);
116     else if ( !Saig_SimObjFaninC0(pObj) && Saig_SimObjFaninC1(pObj) )
117         pObj->pData[0] = (pObj0->pData[0] & ~pObj1->pData[0]);
118     else // if ( !Saig_SimObjFaninC0(pObj) && !Saig_SimObjFaninC1(pObj) )
119         pObj->pData[0] = (pObj0->pData[0] & pObj1->pData[0]);
120 }
121 
122 /**Function*************************************************************
123 
124   Synopsis    [Simulated one node.]
125 
126   Description []
127 
128   SideEffects []
129 
130   SeeAlso     []
131 
132 ***********************************************************************/
Saig_ManSimulateNode(Saig_SimObj_t * pAig,Saig_SimObj_t * pObj)133 static inline void Saig_ManSimulateNode( Saig_SimObj_t * pAig, Saig_SimObj_t * pObj )
134 {
135     Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pObj );
136     Saig_SimObj_t * pObj1 = pAig + Saig_SimObjFanin1( pObj );
137     pObj->pData[0] = (Saig_SimObjFaninC0(pObj)? ~pObj0->pData[0] : pObj0->pData[0])
138         & (Saig_SimObjFaninC1(pObj)? ~pObj1->pData[0] : pObj1->pData[0]);
139 }
140 
141 /**Function*************************************************************
142 
143   Synopsis    [Simulated buffer/inverter.]
144 
145   Description []
146 
147   SideEffects []
148 
149   SeeAlso     []
150 
151 ***********************************************************************/
Saig_ManSimulateOneInput(Saig_SimObj_t * pAig,Saig_SimObj_t * pObj)152 static inline void Saig_ManSimulateOneInput( Saig_SimObj_t * pAig, Saig_SimObj_t * pObj )
153 {
154     Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pObj );
155     if ( Saig_SimObjFaninC0(pObj) )
156         pObj->pData[0] = ~pObj0->pData[0];
157     else // if ( !Saig_SimObjFaninC0(pObj) )
158         pObj->pData[0] = pObj0->pData[0];
159 }
160 
161 /**Function*************************************************************
162 
163   Synopsis    [Simulates the timeframes.]
164 
165   Description []
166 
167   SideEffects []
168 
169   SeeAlso     []
170 
171 ***********************************************************************/
Saig_ManSimulateFrames(Saig_SimObj_t * pAig,int nFrames,int nPref)172 void Saig_ManSimulateFrames( Saig_SimObj_t * pAig, int nFrames, int nPref )
173 {
174     Saig_SimObj_t * pEntry;
175     int f;
176     for ( f = 0; f < nFrames; f++ )
177     {
178         for ( pEntry = pAig; pEntry->Type != AIG_OBJ_VOID; pEntry++ )
179         {
180             if ( pEntry->Type == AIG_OBJ_AND )
181                 Saig_ManSimulateNode( pAig, pEntry );
182             else if ( pEntry->Type == AIG_OBJ_CO )
183                 Saig_ManSimulateOneInput( pAig, pEntry );
184             else if ( pEntry->Type == AIG_OBJ_CI )
185             {
186                 if ( pEntry->iFan0 == 0 ) // true PI
187                     pEntry->pData[0] = Aig_ManRandom( 0 );
188                 else if ( f > 0 ) // register output
189                     Saig_ManSimulateOneInput( pAig, pEntry );
190             }
191             else if ( pEntry->Type == AIG_OBJ_CONST1 )
192                 pEntry->pData[0] = ~0;
193             else if ( pEntry->Type != AIG_OBJ_NONE )
194                 assert( 0 );
195             if ( f >= nPref )
196                 pEntry->Number += Aig_WordCountOnes( pEntry->pData[0] );
197         }
198     }
199 }
200 
201 /**Function*************************************************************
202 
203   Synopsis    [Computes switching activity of one node.]
204 
205   Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
206 
207   SideEffects []
208 
209   SeeAlso     []
210 
211 ***********************************************************************/
Saig_ManComputeSwitching(int nOnes,int nSimWords)212 float Saig_ManComputeSwitching( int nOnes, int nSimWords )
213 {
214     int nTotal = 32 * nSimWords;
215     return (float)2.0 * nOnes / nTotal * (nTotal - nOnes) / nTotal;
216 }
217 
218 /**Function*************************************************************
219 
220   Synopsis    [Computes switching activity of one node.]
221 
222   Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
223 
224   SideEffects []
225 
226   SeeAlso     []
227 
228 ***********************************************************************/
Saig_ManComputeProbOne(int nOnes,int nSimWords)229 float Saig_ManComputeProbOne( int nOnes, int nSimWords )
230 {
231     int nTotal = 32 * nSimWords;
232     return (float)nOnes / nTotal;
233 }
234 
235 /**Function*************************************************************
236 
237   Synopsis    [Computes switching activity of one node.]
238 
239   Description [Uses the formula: Switching = 2 * nOnes * nZeros / (nTotal ^ 2) ]
240 
241   SideEffects []
242 
243   SeeAlso     []
244 
245 ***********************************************************************/
Saig_ManComputeProbOnePlus(int nOnes,int nSimWords,int fCompl)246 float Saig_ManComputeProbOnePlus( int nOnes, int nSimWords, int fCompl )
247 {
248     int nTotal = 32 * nSimWords;
249     if ( fCompl )
250         return (float)(nTotal-nOnes) / nTotal;
251     else
252         return (float)nOnes / nTotal;
253 }
254 
255 /**Function*************************************************************
256 
257   Synopsis    [Compute switching probabilities of all nodes.]
258 
259   Description []
260 
261   SideEffects []
262 
263   SeeAlso     []
264 
265 ***********************************************************************/
Saig_ManComputeSwitchProb4s(Aig_Man_t * p,int nFrames,int nPref,int fProbOne)266 Vec_Int_t * Saig_ManComputeSwitchProb4s( Aig_Man_t * p, int nFrames, int nPref, int fProbOne )
267 {
268     Saig_SimObj_t * pAig, * pEntry;
269     Vec_Int_t * vSwitching;
270     float * pSwitching;
271     int nFramesReal;
272     abctime clk;//, clkTotal = Abc_Clock();
273     vSwitching = Vec_IntStart( Aig_ManObjNumMax(p) );
274     pSwitching = (float *)vSwitching->pArray;
275 clk = Abc_Clock();
276     pAig = Saig_ManCreateMan( p );
277 //ABC_PRT( "\nCreation  ", Abc_Clock() - clk );
278 
279     Aig_ManRandom( 1 );
280     // get the number of  frames to simulate
281     // if the parameter "seqsimframes" is defined, use it
282     // otherwise, use the given number of frames "nFrames"
283     nFramesReal = nFrames;
284     if ( Abc_FrameReadFlag("seqsimframes") )
285         nFramesReal = atoi( Abc_FrameReadFlag("seqsimframes") );
286     if ( nFramesReal <= nPref )
287     {
288         printf( "The total number of frames (%d) should exceed prefix (%d).\n", nFramesReal, nPref );\
289         printf( "Setting the total number of frames to be %d.\n", nFrames );
290         nFramesReal = nFrames;
291     }
292 //printf( "Simulating %d frames.\n", nFramesReal );
293 clk = Abc_Clock();
294     Saig_ManSimulateFrames( pAig, nFramesReal, nPref );
295 //ABC_PRT( "Simulation", Abc_Clock() - clk );
296 clk = Abc_Clock();
297     for ( pEntry = pAig; pEntry->Type != AIG_OBJ_VOID; pEntry++ )
298     {
299 /*
300         if ( pEntry->Type == AIG_OBJ_AND )
301         {
302         Saig_SimObj_t * pObj0 = pAig + Saig_SimObjFanin0( pEntry );
303         Saig_SimObj_t * pObj1 = pAig + Saig_SimObjFanin1( pEntry );
304         printf( "%5.2f = %5.2f * %5.2f  (%7.4f)\n",
305             Saig_ManComputeProbOnePlus( pEntry->Number, nFrames - nPref, 0 ),
306             Saig_ManComputeProbOnePlus( pObj0->Number, nFrames - nPref, Saig_SimObjFaninC0(pEntry) ),
307             Saig_ManComputeProbOnePlus( pObj1->Number, nFrames - nPref, Saig_SimObjFaninC1(pEntry) ),
308             Saig_ManComputeProbOnePlus( pEntry->Number, nFrames - nPref, 0 ) -
309             Saig_ManComputeProbOnePlus( pObj0->Number, nFrames - nPref, Saig_SimObjFaninC0(pEntry) ) *
310             Saig_ManComputeProbOnePlus( pObj1->Number, nFrames - nPref, Saig_SimObjFaninC1(pEntry) )
311             );
312         }
313 */
314         if ( fProbOne )
315             pSwitching[pEntry-pAig] = Saig_ManComputeProbOne( pEntry->Number, nFramesReal - nPref );
316         else
317             pSwitching[pEntry-pAig] = Saig_ManComputeSwitching( pEntry->Number, nFramesReal - nPref );
318 //printf( "%3d : %7.2f\n", pEntry-pAig, pSwitching[pEntry-pAig] );
319     }
320     ABC_FREE( pAig );
321 //ABC_PRT( "Switch    ", Abc_Clock() - clk );
322 //ABC_PRT( "TOTAL     ", Abc_Clock() - clkTotal );
323 
324 //    Aig_CManCreate( p );
325     return vSwitching;
326 }
327 
328 
329 
330 
331 typedef struct Aig_CMan_t_ Aig_CMan_t;
332 struct Aig_CMan_t_
333 {
334     // parameters
335     int             nIns;
336     int             nNodes;
337     int             nOuts;
338     // current state
339     int             iNode;
340     int             iDiff0;
341     int             iDiff1;
342     unsigned char * pCur;
343     // stored data
344     int             iPrev;
345     int             nBytes;
346     unsigned char   Data[0];
347 };
348 
349 
350 /**Function*************************************************************
351 
352   Synopsis    []
353 
354   Description []
355 
356   SideEffects []
357 
358   SeeAlso     []
359 
360 ***********************************************************************/
Aig_CManStart(int nIns,int nNodes,int nOuts)361 Aig_CMan_t * Aig_CManStart( int nIns, int nNodes, int nOuts )
362 {
363     Aig_CMan_t * p;
364     p = (Aig_CMan_t *)ABC_ALLOC( char, sizeof(Aig_CMan_t) + 2*(2*nNodes + nOuts) );
365     memset( p, 0, sizeof(Aig_CMan_t) );
366     // set parameters
367     p->nIns = nIns;
368     p->nOuts = nOuts;
369     p->nNodes = nNodes;
370     p->nBytes = 2*(2*nNodes + nOuts);
371     // prepare the manager
372     p->iNode = 1 + p->nIns;
373     p->iPrev = -1;
374     p->pCur = p->Data;
375     return p;
376 }
377 
378 /**Function*************************************************************
379 
380   Synopsis    []
381 
382   Description []
383 
384   SideEffects []
385 
386   SeeAlso     []
387 
388 ***********************************************************************/
Aig_CManStop(Aig_CMan_t * p)389 void Aig_CManStop( Aig_CMan_t * p )
390 {
391     ABC_FREE( p );
392 }
393 
394 /**Function*************************************************************
395 
396   Synopsis    []
397 
398   Description []
399 
400   SideEffects []
401 
402   SeeAlso     []
403 
404 ***********************************************************************/
Aig_CManRestart(Aig_CMan_t * p)405 void Aig_CManRestart( Aig_CMan_t * p )
406 {
407     assert( p->iNode == 1 + p->nIns + p->nNodes + p->nOuts );
408     p->iNode = 1 + p->nIns;
409     p->iPrev = -1;
410     p->pCur = p->Data;
411 }
412 
413 
414 /**Function*************************************************************
415 
416   Synopsis    []
417 
418   Description []
419 
420   SideEffects []
421 
422   SeeAlso     []
423 
424 ***********************************************************************/
Aig_CManStoreNum(Aig_CMan_t * p,unsigned x)425 void Aig_CManStoreNum( Aig_CMan_t * p, unsigned x )
426 {
427     while ( x & ~0x7f )
428     {
429         *p->pCur++ = (x & 0x7f) | 0x80;
430         x >>= 7;
431     }
432     *p->pCur++ = x;
433     assert( p->pCur - p->Data < p->nBytes - 10 );
434 }
435 
436 /**Function*************************************************************
437 
438   Synopsis    []
439 
440   Description []
441 
442   SideEffects []
443 
444   SeeAlso     []
445 
446 ***********************************************************************/
Aig_CManRestoreNum(Aig_CMan_t * p)447 int Aig_CManRestoreNum( Aig_CMan_t * p )
448 {
449     int ch, i, x = 0;
450     for ( i = 0; (ch = *p->pCur++) & 0x80; i++ )
451         x |= (ch & 0x7f) << (7 * i);
452     return x | (ch << (7 * i));
453 }
454 
455 /**Function*************************************************************
456 
457   Synopsis    []
458 
459   Description []
460 
461   SideEffects []
462 
463   SeeAlso     []
464 
465 ***********************************************************************/
Aig_CManAddNode(Aig_CMan_t * p,int iFan0,int iFan1)466 void Aig_CManAddNode( Aig_CMan_t * p, int iFan0, int iFan1 )
467 {
468     assert( iFan0 < iFan1 );
469     assert( iFan1 < (p->iNode << 1) );
470     Aig_CManStoreNum( p, (p->iNode++ << 1) - iFan1 );
471     Aig_CManStoreNum( p, iFan1 - iFan0 );
472 }
473 
474 /**Function*************************************************************
475 
476   Synopsis    []
477 
478   Description []
479 
480   SideEffects []
481 
482   SeeAlso     []
483 
484 ***********************************************************************/
Aig_CManAddPo(Aig_CMan_t * p,int iFan0)485 void Aig_CManAddPo( Aig_CMan_t * p, int iFan0 )
486 {
487     if ( p->iPrev == -1 )
488         Aig_CManStoreNum( p, p->iNode - iFan0 );
489     else if ( p->iPrev <= iFan0 )
490         Aig_CManStoreNum( p, (iFan0 - p->iPrev) << 1 );
491     else
492         Aig_CManStoreNum( p,((p->iPrev - iFan0) << 1) | 1 );
493     p->iPrev = iFan0;
494     p->iNode++;
495 }
496 
497 /**Function*************************************************************
498 
499   Synopsis    []
500 
501   Description []
502 
503   SideEffects []
504 
505   SeeAlso     []
506 
507 ***********************************************************************/
Aig_CManGetNode(Aig_CMan_t * p,int * piFan0,int * piFan1)508 void Aig_CManGetNode( Aig_CMan_t * p, int * piFan0, int * piFan1 )
509 {
510     *piFan1 = (p->iNode++ << 1) - Aig_CManRestoreNum( p );
511     *piFan0 = *piFan1 - Aig_CManRestoreNum( p );
512 }
513 
514 /**Function*************************************************************
515 
516   Synopsis    []
517 
518   Description []
519 
520   SideEffects []
521 
522   SeeAlso     []
523 
524 ***********************************************************************/
Aig_CManGetPo(Aig_CMan_t * p)525 int Aig_CManGetPo( Aig_CMan_t * p )
526 {
527     int Num = Aig_CManRestoreNum( p );
528     if ( p->iPrev == -1 )
529         p->iPrev = p->iNode;
530     p->iNode++;
531     if ( Num & 1 )
532         return p->iPrev = p->iPrev + (Num >> 1);
533     return p->iPrev = p->iPrev - (Num >> 1);
534 }
535 
536 /**Function*************************************************************
537 
538   Synopsis    [Compute switching probabilities of all nodes.]
539 
540   Description []
541 
542   SideEffects []
543 
544   SeeAlso     []
545 
546 ***********************************************************************/
Aig_CManCreate(Aig_Man_t * p)547 Aig_CMan_t * Aig_CManCreate( Aig_Man_t * p )
548 {
549     Aig_CMan_t * pCMan;
550     Aig_Obj_t * pObj;
551     int i;
552     pCMan = Aig_CManStart( Aig_ManCiNum(p), Aig_ManNodeNum(p), Aig_ManCoNum(p) );
553     Aig_ManForEachNode( p, pObj, i )
554         Aig_CManAddNode( pCMan,
555             (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj),
556             (Aig_ObjFaninId1(pObj) << 1) | Aig_ObjFaninC1(pObj) );
557     Aig_ManForEachCo( p, pObj, i )
558         Aig_CManAddPo( pCMan,
559             (Aig_ObjFaninId0(pObj) << 1) | Aig_ObjFaninC0(pObj) );
560     printf( "\nBytes alloc = %5d.  Bytes used = %7d.  Ave per node = %4.2f. \n",
561         pCMan->nBytes, (int)(pCMan->pCur - pCMan->Data),
562         1.0 * (pCMan->pCur - pCMan->Data) / (pCMan->nNodes + pCMan->nOuts ) );
563 //    Aig_CManStop( pCMan );
564     return pCMan;
565 }
566 
567 ////////////////////////////////////////////////////////////////////////
568 ///                       END OF FILE                                ///
569 ////////////////////////////////////////////////////////////////////////
570 
571 
572 ABC_NAMESPACE_IMPL_END
573 
574