gem5  v21.1.0.2
traffic_gen.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2013, 2016-2020 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  */
38 
39 #include <libgen.h>
40 #include <unistd.h>
41 
42 #include <cmath>
43 #include <fstream>
44 #include <sstream>
45 
46 #include "base/intmath.hh"
47 #include "base/random.hh"
48 #include "debug/TrafficGen.hh"
49 #include "params/TrafficGen.hh"
50 #include "sim/stats.hh"
51 #include "sim/system.hh"
52 
53 namespace gem5
54 {
55 
56 TrafficGen::TrafficGen(const TrafficGenParams &p)
57  : BaseTrafficGen(p),
58  configFile(p.config_file),
59  currState(0)
60 {
61 }
62 
63 void
65 {
67 
68  parseConfig();
69 }
70 
71 void
73 {
75 
76  // when not restoring from a checkpoint, make sure we kick things off
77  if (system->isTimingMode()) {
78  DPRINTF(TrafficGen, "Timing mode, activating request generator\n");
79  start();
80  } else {
82  "Traffic generator is only active in timing mode\n");
83  }
84 }
85 
86 void
88 {
90 
92 }
93 
94 void
96 {
97  // @todo In the case of a stateful generator state such as the
98  // trace player we would also have to restore the position in the
99  // trace playback and the tick offset
101 
103 }
104 
105 std::string
106 TrafficGen::resolveFile(const std::string &name)
107 {
108  // Do nothing for empty and absolute file names
109  if (name.empty() || name[0] == '/')
110  return name;
111 
112  char *config_path = strdup(configFile.c_str());
113  char *config_dir = dirname(config_path);
114  const std::string config_rel = csprintf("%s/%s", config_dir, name);
115  free(config_path);
116 
117  // Check the path relative to the config file first
118  if (access(config_rel.c_str(), R_OK) == 0)
119  return config_rel;
120 
121  // Fall back to the old behavior and search relative to the
122  // current working directory.
123  return name;
124 }
125 
126 void
128 {
129  // keep track of the transitions parsed to create the matrix when
130  // done
131  std::vector<Transition> transitions;
132 
133  // open input file
134  std::ifstream infile;
135  infile.open(configFile.c_str(), std::ifstream::in);
136  if (!infile.is_open()) {
137  fatal("Traffic generator %s config file not found at %s\n",
138  name(), configFile);
139  }
140 
141  bool init_state_set = false;
142 
143  // read line by line and determine the action based on the first
144  // keyword
145  std::string keyword;
146  std::string line;
147 
148  while (getline(infile, line).good()) {
149  // see if this line is a comment line, and if so skip it
150  if (line.find('#') != 1) {
151  // create an input stream for the tokenization
152  std::istringstream is(line);
153 
154  // determine the keyword
155  is >> keyword;
156 
157  if (keyword == "STATE") {
158  // parse the behaviour of this state
159  uint32_t id;
160  Tick duration;
161  std::string mode;
162 
163  is >> id >> duration >> mode;
164 
165  if (mode == "TRACE") {
166  std::string traceFile;
167  Addr addrOffset;
168 
169  is >> traceFile >> addrOffset;
170  traceFile = resolveFile(traceFile);
171 
172  states[id] = createTrace(duration, traceFile, addrOffset);
173  DPRINTF(TrafficGen, "State: %d TraceGen\n", id);
174  } else if (mode == "IDLE") {
175  states[id] = createIdle(duration);
176  DPRINTF(TrafficGen, "State: %d IdleGen\n", id);
177  } else if (mode == "EXIT") {
178  states[id] = createExit(duration);
179  DPRINTF(TrafficGen, "State: %d ExitGen\n", id);
180  } else if (mode == "LINEAR" || mode == "RANDOM" ||
181  mode == "DRAM" || mode == "DRAM_ROTATE" ||
182  mode == "NVM") {
183  uint32_t read_percent;
184  Addr start_addr;
185  Addr end_addr;
186  Addr blocksize;
187  Tick min_period;
188  Tick max_period;
189  Addr data_limit;
190 
191  is >> read_percent >> start_addr >> end_addr >>
192  blocksize >> min_period >> max_period >> data_limit;
193 
194  DPRINTF(TrafficGen, "%s, addr %x to %x, size %d,"
195  " period %d to %d, %d%% reads\n",
196  mode, start_addr, end_addr, blocksize, min_period,
197  max_period, read_percent);
198 
199 
200  if (mode == "LINEAR") {
201  states[id] = createLinear(duration, start_addr,
202  end_addr, blocksize,
203  min_period, max_period,
204  read_percent, data_limit);
205  DPRINTF(TrafficGen, "State: %d LinearGen\n", id);
206  } else if (mode == "RANDOM") {
207  states[id] = createRandom(duration, start_addr,
208  end_addr, blocksize,
209  min_period, max_period,
210  read_percent, data_limit);
211  DPRINTF(TrafficGen, "State: %d RandomGen\n", id);
212  } else if (mode == "DRAM" || mode == "DRAM_ROTATE" ||
213  mode == "NVM") {
214  // stride size (bytes) of the request for achieving
215  // required hit length
216  unsigned int stride_size;
217  unsigned int page_size;
218  unsigned int nbr_of_banks;
219  unsigned int nbr_of_banks_util;
220  unsigned _addr_mapping;
221  unsigned int nbr_of_ranks;
222 
223  is >> stride_size >> page_size >> nbr_of_banks >>
224  nbr_of_banks_util >> _addr_mapping >>
225  nbr_of_ranks;
226  enums::AddrMap addr_mapping =
227  static_cast<enums::AddrMap>(_addr_mapping);
228 
229  if (stride_size > page_size)
230  warn("Memory generator stride size (%d) is greater"
231  " than page size (%d) of the memory\n",
232  blocksize, page_size);
233 
234  // count the number of sequential packets to
235  // generate
236  unsigned int num_seq_pkts = 1;
237 
238  if (stride_size > blocksize) {
239  num_seq_pkts = divCeil(stride_size, blocksize);
240  DPRINTF(TrafficGen, "stride size: %d "
241  "block size: %d, num_seq_pkts: %d\n",
242  stride_size, blocksize, num_seq_pkts);
243  }
244 
245  if (mode == "DRAM") {
246  states[id] = createDram(duration, start_addr,
247  end_addr, blocksize,
248  min_period, max_period,
249  read_percent, data_limit,
250  num_seq_pkts, page_size,
251  nbr_of_banks,
252  nbr_of_banks_util,
253  addr_mapping,
254  nbr_of_ranks);
255  DPRINTF(TrafficGen, "State: %d DramGen\n", id);
256  } else if (mode == "DRAM_ROTATE") {
257  // Will rotate to the next rank after rotating
258  // through all banks, for each command type.
259  // In the 50% read case, series will be issued
260  // for both RD & WR before the rank in incremented
261  unsigned int max_seq_count_per_rank =
262  (read_percent == 50) ? nbr_of_banks_util * 2
263  : nbr_of_banks_util;
264 
265  states[id] = createDramRot(duration, start_addr,
266  end_addr, blocksize,
267  min_period, max_period,
268  read_percent,
269  data_limit,
270  num_seq_pkts, page_size,
271  nbr_of_banks,
272  nbr_of_banks_util,
273  addr_mapping,
274  nbr_of_ranks,
275  max_seq_count_per_rank);
276  DPRINTF(TrafficGen, "State: %d DramRotGen\n", id);
277  } else {
278  states[id] = createNvm(duration, start_addr,
279  end_addr, blocksize,
280  min_period, max_period,
281  read_percent, data_limit,
282  num_seq_pkts, page_size,
283  nbr_of_banks,
284  nbr_of_banks_util,
285  addr_mapping,
286  nbr_of_ranks);
287  DPRINTF(TrafficGen, "State: %d NvmGen\n", id);
288  }
289  }
290  } else {
291  fatal("%s: Unknown traffic generator mode: %s",
292  name(), mode);
293  }
294  } else if (keyword == "TRANSITION") {
296 
297  is >> transition.from >> transition.to >> transition.p;
298 
299  transitions.push_back(transition);
300 
301  DPRINTF(TrafficGen, "Transition: %d -> %d\n", transition.from,
302  transition.to);
303  } else if (keyword == "INIT") {
304  // set the initial state as the active state
305  is >> currState;
306 
307  init_state_set = true;
308 
309  DPRINTF(TrafficGen, "Initial state: %d\n", currState);
310  }
311  }
312  }
313 
314  if (!init_state_set)
315  fatal("%s: initial state not specified (add 'INIT <id>' line "
316  "to the config file)\n", name());
317 
318  // resize and populate state transition matrix
319  transitionMatrix.resize(states.size());
320  for (size_t i = 0; i < states.size(); i++) {
321  transitionMatrix[i].resize(states.size());
322  }
323 
324  for (std::vector<Transition>::iterator t = transitions.begin();
325  t != transitions.end(); ++t) {
326  transitionMatrix[t->from][t->to] = t->p;
327  }
328 
329  // ensure the egress edges do not have a probability larger than
330  // one
331  for (size_t i = 0; i < states.size(); i++) {
332  double sum = 0;
333  for (size_t j = 0; j < states.size(); j++) {
334  sum += transitionMatrix[i][j];
335  }
336 
337  // avoid comparing floating point numbers
338  if (std::fabs(sum - 1.0) > 0.001) {
339  fatal("%s has transition probability != 1 for state %d\n",
340  name(), i);
341  }
342  }
343 
344  // close input file
345  infile.close();
346 }
347 
348 size_t
350 {
351  double p = random_mt.random<double>();
352  assert(currState < transitionMatrix.size());
353  double cumulative = 0.0;
354  size_t i = 0;
355  do {
356  cumulative += transitionMatrix[currState][i];
357  ++i;
358  } while (cumulative < p && i < transitionMatrix[currState].size());
359 
360  return i - 1;
361 }
362 
363 std::shared_ptr<BaseGen>
365 {
366  // Return the initial state if there isn't an active generator,
367  // otherwise perform a state transition.
368  if (activeGenerator)
369  currState = nextState();
370 
371  DPRINTF(TrafficGen, "Transition to state %d\n", currState);
372  return states[currState];
373 }
374 
375 } // namespace gem5
gem5::BaseTrafficGen::createLinear
std::shared_ptr< BaseGen > createLinear(Tick duration, Addr start_addr, Addr end_addr, Addr blocksize, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit)
Definition: base.cc:384
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:189
traffic_gen.hh
gem5::TrafficGen::initState
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: traffic_gen.cc:72
gem5::SimObject::initState
virtual void initState()
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: sim_object.cc:94
warn
#define warn(...)
Definition: logging.hh:245
system.hh
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::TrafficGen::nextState
size_t nextState()
Use the transition matrix to find the next state index.
Definition: traffic_gen.cc:349
gem5::TrafficGen::parseConfig
void parseConfig()
Parse the config file and build the state map and transition matrix.
Definition: traffic_gen.cc:127
gem5::CheckpointIn
Definition: serialize.hh:68
random.hh
gem5::BaseTrafficGen::createIdle
std::shared_ptr< BaseGen > createIdle(Tick duration)
Definition: base.cc:370
gem5::TrafficGen::nextGenerator
std::shared_ptr< BaseGen > nextGenerator() override
Definition: traffic_gen.cc:364
gem5::BaseTrafficGen::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: base.cc:152
gem5::TrafficGen::Transition
Struct to represent a probabilistic transition during parsing.
Definition: traffic_gen.hh:106
std::vector
STL vector class.
Definition: stl.hh:37
gem5::TrafficGen::resolveFile
std::string resolveFile(const std::string &name)
Resolve a file path in the configuration file.
Definition: traffic_gen.cc:106
gem5::csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
gem5::BaseTrafficGen::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: base.cc:104
gem5::TrafficGen::transitionMatrix
std::vector< std::vector< double > > transitionMatrix
State transition matrix.
Definition: traffic_gen.hh:114
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::TrafficGen::currState
uint32_t currState
Index of the current state.
Definition: traffic_gen.hh:117
gem5::MipsISA::is
Bitfield< 24, 22 > is
Definition: pra_constants.hh:235
stats.hh
gem5::ArmISA::j
Bitfield< 24 > j
Definition: misc_types.hh:57
gem5::Random::random
std::enable_if_t< std::is_integral< T >::value, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
Definition: random.hh:90
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::TrafficGen::configFile
const std::string configFile
The config file to parse.
Definition: traffic_gen.hh:76
gem5::BaseTrafficGen::createDram
std::shared_ptr< BaseGen > createDram(Tick duration, Addr start_addr, Addr end_addr, Addr blocksize, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit, unsigned int num_seq_pkts, unsigned int page_size, unsigned int nbr_of_banks, unsigned int nbr_of_banks_util, enums::AddrMap addr_mapping, unsigned int nbr_of_ranks)
Definition: base.cc:412
gem5::BaseTrafficGen::createNvm
std::shared_ptr< BaseGen > createNvm(Tick duration, Addr start_addr, Addr end_addr, Addr blocksize, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit, unsigned int num_seq_pkts, unsigned int buffer_size, unsigned int nbr_of_banks, unsigned int nbr_of_banks_util, enums::AddrMap addr_mapping, unsigned int nbr_of_ranks)
Definition: base.cc:506
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::BaseTrafficGen::createTrace
std::shared_ptr< BaseGen > createTrace(Tick duration, const std::string &trace_file, Addr addr_offset)
Definition: base.cc:546
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::TrafficGen::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: traffic_gen.cc:87
gem5::BaseTrafficGen::start
void start()
Definition: base.cc:282
gem5::BaseTrafficGen
The traffic generator is a module that generates stimuli for the memory system, based on a collection...
Definition: base.hh:67
gem5::BaseTrafficGen::transition
void transition()
Transition to the next generator.
Definition: base.cc:230
gem5::BaseTrafficGen::system
System *const system
The system used to determine which mode we are currently operating in.
Definition: base.hh:76
gem5::System::isTimingMode
bool isTimingMode() const
Is the system in timing mode?
Definition: system.hh:276
gem5::ArmISA::t
Bitfield< 5 > t
Definition: misc_types.hh:70
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
name
const std::string & name()
Definition: trace.cc:49
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
gem5::divCeil
static constexpr T divCeil(const T &a, const U &b)
Definition: intmath.hh:110
gem5::TrafficGen::states
std::unordered_map< uint32_t, std::shared_ptr< BaseGen > > states
Map of generator states.
Definition: traffic_gen.hh:120
gem5::TrafficGen::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: traffic_gen.cc:95
gem5::BaseTrafficGen::createDramRot
std::shared_ptr< BaseGen > createDramRot(Tick duration, Addr start_addr, Addr end_addr, Addr blocksize, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit, unsigned int num_seq_pkts, unsigned int page_size, unsigned int nbr_of_banks, unsigned int nbr_of_banks_util, enums::AddrMap addr_mapping, unsigned int nbr_of_ranks, unsigned int max_seq_count_per_rank)
Definition: base.cc:436
gem5::BaseTrafficGen::activeGenerator
std::shared_ptr< BaseGen > activeGenerator
Currently active generator.
Definition: base.hh:343
gem5::TrafficGen
The traffic generator is a module that generates stimuli for the memory system, based on a collection...
Definition: traffic_gen.hh:70
gem5::ArmISA::id
Bitfield< 33 > id
Definition: misc_types.hh:250
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::RiscvISA::sum
Bitfield< 18 > sum
Definition: misc.hh:545
intmath.hh
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::BaseTrafficGen::createRandom
std::shared_ptr< BaseGen > createRandom(Tick duration, Addr start_addr, Addr end_addr, Addr blocksize, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit)
Definition: base.cc:398
gem5::random_mt
Random random_mt
Definition: random.cc:99
gem5::BaseTrafficGen::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: base.cc:132
gem5::TrafficGen::TrafficGen
TrafficGen(const TrafficGenParams &p)
Definition: traffic_gen.cc:56
gem5::ArmISA::mode
Bitfield< 4, 0 > mode
Definition: misc_types.hh:73
gem5::TrafficGen::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: traffic_gen.cc:64
gem5::BaseTrafficGen::createExit
std::shared_ptr< BaseGen > createExit(Tick duration)
Definition: base.cc:377

Generated on Tue Sep 21 2021 12:25:09 for gem5 by doxygen 1.8.17