48#include "debug/TrafficGen.hh"
49#include "params/TrafficGen.hh"
58 configFile(
p.config_file),
82 "Traffic generator is only active in timing mode\n");
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);
118 if (access(config_rel.c_str(), R_OK) == 0)
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",
141 bool init_state_set =
false;
148 while (getline(infile, line).good()) {
150 if (line.find(
'#') != 1) {
152 std::istringstream
is(line);
157 if (keyword ==
"STATE") {
163 is >>
id >> duration >>
mode;
165 if (
mode ==
"TRACE") {
166 std::string traceFile;
169 is >> traceFile >> addrOffset;
174 }
else if (
mode ==
"IDLE") {
177 }
else if (
mode ==
"EXIT") {
180 }
else if (
mode ==
"LINEAR" ||
mode ==
"RANDOM" ||
181 mode ==
"DRAM" ||
mode ==
"DRAM_ROTATE" ||
183 uint32_t read_percent;
191 is >> read_percent >> start_addr >> end_addr >>
192 blocksize >> min_period >> max_period >> data_limit;
195 " period %d to %d, %d%% reads\n",
196 mode, start_addr, end_addr, blocksize, min_period,
197 max_period, read_percent);
200 if (
mode ==
"LINEAR") {
203 min_period, max_period,
204 read_percent, data_limit);
206 }
else if (
mode ==
"RANDOM") {
209 min_period, max_period,
210 read_percent, data_limit);
212 }
else if (
mode ==
"DRAM" ||
mode ==
"DRAM_ROTATE" ||
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;
223 is >> stride_size >> page_size >> nbr_of_banks >>
224 nbr_of_banks_util >> _addr_mapping >>
226 enums::AddrMap addr_mapping =
227 static_cast<enums::AddrMap
>(_addr_mapping);
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);
236 unsigned int num_seq_pkts = 1;
238 if (stride_size > blocksize) {
239 num_seq_pkts =
divCeil(stride_size, blocksize);
241 "block size: %d, num_seq_pkts: %d\n",
242 stride_size, blocksize, num_seq_pkts);
245 if (
mode ==
"DRAM") {
248 min_period, max_period,
249 read_percent, data_limit,
250 num_seq_pkts, page_size,
256 }
else if (
mode ==
"DRAM_ROTATE") {
261 unsigned int max_seq_count_per_rank =
262 (read_percent == 50) ? nbr_of_banks_util * 2
267 min_period, max_period,
270 num_seq_pkts, page_size,
275 max_seq_count_per_rank);
280 min_period, max_period,
281 read_percent, data_limit,
282 num_seq_pkts, page_size,
290 }
else if (
mode ==
"STRIDED") {
291 uint32_t read_percent;
296 Addr superblock_size;
302 is >> read_percent >> start_addr >> end_addr >>
offset >>
303 blocksize >> superblock_size >> stride_size >>
304 min_period >> max_period >> data_limit;
307 "size %d, super size %d, stride size %d, "
308 "period %d to %d, %d%% reads\n",
309 mode, start_addr, end_addr,
offset, blocksize,
310 superblock_size, stride_size, min_period,
311 max_period, read_percent);
314 duration, start_addr, end_addr,
offset,
315 blocksize, superblock_size, stride_size,
316 min_period, max_period, read_percent, data_limit);
320 fatal(
"%s: Unknown traffic generator mode: %s",
323 }
else if (keyword ==
"TRANSITION") {
332 }
else if (keyword ==
"INIT") {
336 init_state_set =
true;
344 fatal(
"%s: initial state not specified (add 'INIT <id>' line "
345 "to the config file)\n",
name());
349 for (
size_t i = 0;
i <
states.size();
i++) {
354 t != transitions.end(); ++
t) {
360 for (
size_t i = 0;
i <
states.size();
i++) {
362 for (
size_t j = 0; j <
states.size(); j++) {
367 if (std::fabs(
sum - 1.0) > 0.001) {
368 fatal(
"%s has transition probability != 1 for state %d\n",
382 double cumulative = 0.0;
392std::shared_ptr<BaseGen>
The traffic generator is a module that generates stimuli for the memory system, based on a collection...
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
std::shared_ptr< BaseGen > createIdle(Tick duration)
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)
std::shared_ptr< BaseGen > createTrace(Tick duration, const std::string &trace_file, Addr addr_offset)
std::shared_ptr< BaseGen > createStrided(Tick duration, Addr start_addr, Addr end_addr, Addr offset, Addr block_size, Addr superblock_size, Addr stride_size, Tick min_period, Tick max_period, uint8_t read_percent, Addr data_limit)
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)
void transition()
Transition to the next generator.
System *const system
The system used to determine which mode we are currently operating in.
std::shared_ptr< BaseGen > activeGenerator
Currently active generator.
std::shared_ptr< BaseGen > createExit(Tick duration)
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)
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)
void serialize(CheckpointOut &cp) const override
Serialize an object.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
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)
virtual std::string name() const
bool isTimingMode() const
Is the system in timing mode?
The traffic generator is a module that generates stimuli for the memory system, based on a collection...
void serialize(CheckpointOut &cp) const override
Serialize an object.
void parseConfig()
Parse the config file and build the state map and transition matrix.
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
std::shared_ptr< BaseGen > nextGenerator() override
uint32_t currState
Index of the current state.
TrafficGen(const TrafficGenParams &p)
std::unordered_map< uint32_t, std::shared_ptr< BaseGen > > states
Map of generator states.
const std::string configFile
The config file to parse.
size_t nextState()
Use the transition matrix to find the next state index.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
std::string resolveFile(const std::string &name)
Resolve a file path in the configuration file.
std::vector< std::vector< double > > transitionMatrix
State transition matrix.
static constexpr T divCeil(const T &a, const U &b)
std::enable_if_t< std::is_integral_v< T >, T > random()
Use the SFINAE idiom to choose an implementation based on whether the type is integral or floating po...
#define fatal(...)
This implements a cprintf based fatal() function.
virtual void initState()
initState() is called on each SimObject when not restoring from a checkpoint.
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::ostream CheckpointOut
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint64_t Tick
Tick count type.
std::string csprintf(const char *format, const Args &...args)
#define UNSERIALIZE_SCALAR(scalar)
#define SERIALIZE_SCALAR(scalar)
Struct to represent a probabilistic transition during parsing.
const std::string & name()