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