summaryrefslogtreecommitdiff
path: root/src/intersim/injection.cpp
blob: 68483cb540fcd3bbdf653df511fb19b18fa7fb8e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include "booksim.hpp"
#include <map>
#include <assert.h>
#include <cstdlib>
#include "injection.hpp"
#include "network.hpp"
#include "random_utils.hpp"
#include "misc_utils.hpp"

map<string, tInjectionProcess> gInjectionProcessMap;

double gBurstAlpha;
double gBurstBeta;

int    gConstPacketSize;

int *gNodeStates = 0;
//=============================================================

int bernoulli( int /*source*/, double rate )
{
   return( RandomFloat( ) < ( rate / (double)gConstPacketSize ) ) ? 
   gConstPacketSize : 0;
}

//=============================================================

int on_off( int source, double rate )
{
   double r1;
   bool issue;

   assert( ( source >= 0 ) && ( source < gNodes ) );

   if ( !gNodeStates ) {
      gNodeStates = new int [gNodes];

      for ( int n = 0; n < gNodes; ++n ) {
         gNodeStates[n] = 0;
      }
   }

   // advance state

   if ( gNodeStates[source] == 0 ) {
      if ( RandomFloat( ) < gBurstAlpha ) { // from off to on
         gNodeStates[source] = 1;
      }
   } else if ( RandomFloat( ) < gBurstBeta ) { // from on to off
      gNodeStates[source] = 0;
   }

   // generate packet

   issue = false;
   if ( gNodeStates[source] ) { // on?
      r1 = rate * ( 1.0 + gBurstBeta / gBurstAlpha ) / 
           (double)gConstPacketSize;

      if ( RandomFloat( ) < r1 ) {
         issue = true;
      }
   }

   return issue ? gConstPacketSize : 0;
}

//=============================================================

void InitializeInjectionMap( )
{
   /* Register injection processes functions here */

   gInjectionProcessMap["bernoulli"] = &bernoulli;
   gInjectionProcessMap["on_off"]    = &on_off;
}

tInjectionProcess GetInjectionProcess( const Configuration& config )
{
   map<string, tInjectionProcess>::const_iterator match;
   tInjectionProcess ip;

   string fn;

   config.GetStr( "injection_process", fn );
   match = gInjectionProcessMap.find( fn );

   if ( match != gInjectionProcessMap.end( ) ) {
      ip = match->second;
   } else {
      cout << "Error: Undefined injection process '" << fn << "'." << endl;
      exit(-1);
   }

   gConstPacketSize = config.GetInt( "const_flits_per_packet" );
   gBurstAlpha      = config.GetFloat( "burst_alpha" );
   gBurstBeta       = config.GetFloat( "burst_beta" );

   return ip;
}